diff options
Diffstat (limited to 'rt/share/html/Ticket')
53 files changed, 743 insertions, 2002 deletions
diff --git a/rt/share/html/Ticket/Attachment/dhandler b/rt/share/html/Ticket/Attachment/dhandler index a43eba7..134ecd6 100755 --- a/rt/share/html/Ticket/Attachment/dhandler +++ b/rt/share/html/Ticket/Attachment/dhandler @@ -46,52 +46,61 @@ %# %# END BPS TAGGED BLOCK }}} <%perl> - my ($ticket, $trans,$attach, $filename); - my $arg = $m->dhandler_arg; # get rest of path - if ($arg =~ m{^(\d+)/(\d+)}) { - $trans = $1; - $attach = $2; - } - else { - Abort("Corrupted attachment URL."); - } - my $AttachmentObj = RT::Attachment->new($session{'CurrentUser'}); - $AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded"); +my ( $ticket, $trans, $attach, $filename ); +my $arg = $m->dhandler_arg; # get rest of path +if ( $arg =~ m{^(\d+)/(\d+)} ) { + $trans = $1; + $attach = $2; +} +else { + Abort("Corrupted attachment URL."); +} +my $AttachmentObj = RT::Attachment->new( $session{'CurrentUser'} ); +$AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded"); +unless ( $AttachmentObj->id ) { + Abort("Bad attachment id. Couldn't find attachment '$attach'\n"); +} +unless ( $AttachmentObj->TransactionId() == $trans ) { + Abort("Bad transaction number for attachment. $trans should be". $AttachmentObj->TransactionId() . "\n"); +} - unless ($AttachmentObj->id) { - Abort("Bad attachment id. Couldn't find attachment '$attach'\n"); - } - unless ($AttachmentObj->TransactionId() == $trans ) { - Abort("Bad transaction number for attachment. $trans should be".$AttachmentObj->TransactionId() ."\n"); +my $content = $AttachmentObj->OriginalContent; +my $content_type = $AttachmentObj->ContentType || 'text/plain'; - } +if ( RT->Config->Get('AlwaysDownloadAttachments') ) { + $r->headers_out->{'Content-Disposition'} = "attachment"; +} +elsif ( !RT->Config->Get('TrustHTMLAttachments') ) { + $content_type = 'text/plain' if ( $content_type =~ /^text\/html/i ); +} +elsif (lc $content_type eq 'text/html') { + # If we're trusting and serving HTML for display not download, try to do + # inline <img> rewriting to be extra helpful. + my $count = RT::Interface::Web::RewriteInlineImages( + Content => \$content, + Attachment => $AttachmentObj, + ); + RT->Logger->debug("Rewrote $count CID images when displaying original HTML attachment #$attach"); +} - my $content_type = $AttachmentObj->ContentType || 'text/plain'; +my $enc = $AttachmentObj->OriginalEncoding || 'utf-8'; +my $iana = Encode::find_encoding($enc); + $iana = $iana ? $iana->mime_name : $enc; - if (RT->Config->Get('AlwaysDownloadAttachments')) { - $r->headers_out->{'Content-Disposition'} = "attachment"; - } - elsif (!RT->Config->Get('TrustHTMLAttachments')) { - $content_type = 'text/plain' if ($content_type =~ /^text\/html/i); - } +require MIME::Types; +my $mimetype = MIME::Types->new->type($content_type); +unless ( $mimetype && $mimetype->isBinary ) { + $content_type .= ";charset=$iana"; +} - my $enc = $AttachmentObj->OriginalEncoding || 'utf-8'; - my $iana = Encode::find_encoding( $enc ); - $iana = $iana? $iana->mime_name : $enc; - - require MIME::Types; - my $mimetype = MIME::Types->new->type($content_type); - unless ( $mimetype && $mimetype->isBinary ) { - $content_type .= ";charset=$iana"; - } - - $r->subprocess_env('no-gzip' => 1); # disable mod_deflate - $r->content_type( $content_type ); - $m->clear_buffer(); - $m->out($AttachmentObj->OriginalContent); - $m->abort; +$r->subprocess_env('no-gzip' => 1); # disable mod_deflate +$r->content_type($content_type); +$m->clear_buffer(); +$m->out($content); +$m->abort; </%perl> <%attr> AutoFlush => 0 </%attr> + diff --git a/rt/share/html/Ticket/Create.html b/rt/share/html/Ticket/Create.html index 7a1619a..1d18037 100755 --- a/rt/share/html/Ticket/Create.html +++ b/rt/share/html/Ticket/Create.html @@ -55,11 +55,12 @@ <form action="<% RT->Config->Get('WebPath') %>/Ticket/Create.html" method="post" enctype="multipart/form-data" name="TicketCreate"> <input type="submit" name="SubmitTicket" value="Create" style="display:none"> <input type="hidden" class="hidden" name="id" value="new" /> + <input type="hidden" class="hidden" name="Token" value="<% $ARGS{'Token'} %>" /> % $m->callback( CallbackName => 'FormStart', QueueObj => $QueueObj, ARGSRef => \%ARGS ); % if ($gnupg_widget) { - <& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> + <& /Elements/Crypt/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> % } <div id="Ticket-Create-basics"> @@ -83,12 +84,9 @@ }, }, { name => 'Status', - comp => '/Elements/SelectStatus', + comp => '/Ticket/Elements/SelectStatus', args => { Name => "Status", - Default => $ARGS{Status} || $QueueObj->Lifecycle->DefaultOnCreate, - DefaultValue => 0, - SkipDeleted => 1, QueueObj => $QueueObj, }, }, @@ -106,11 +104,26 @@ % $m->callback( CallbackName => 'AfterOwner', ARGSRef => \%ARGS ); - <& /Ticket/Elements/EditCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1, KeepValue => 1 &> - <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1, KeepValue => 1 &> + <& /Elements/EditCustomFields, + %ARGS, + Object => $ticket, + CustomFields => $QueueObj->TicketCustomFields, + Grouping => 'Basics', + InTable => 1, + KeepValue => 1, + &> + <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1, KeepValue => 1, &> </table> </&> % $m->callback( CallbackName => 'AfterBasics', QueueObj => $QueueObj, ARGSRef => \%ARGS ); + +<& /Elements/EditCustomFieldCustomGroupings, + %ARGS, + Object => $ticket, + CustomFieldGenerator => sub { $QueueObj->TicketCustomFields }, + KeepValue => 1, +&> + </div> <div id="ticket-create-message"> @@ -121,7 +134,7 @@ <&|/l&>Requestors</&>: </td> <td class="value" colspan="5"> -<& /Elements/EmailInput, Name => 'Requestors', Size => undef, Default => exists($ARGS{Requestors}) ? $ARGS{Requestors} : $session{CurrentUser}->EmailAddress &> +<& /Elements/EmailInput, Name => 'Requestors', Size => undef, Default => $ARGS{Requestors} // $session{CurrentUser}->EmailAddress, AutocompleteMultiple => 1 &> % $m->callback( CallbackName => 'AfterRequestors', QueueObj => $QueueObj, ARGSRef => \%ARGS ); </td> </tr> @@ -129,7 +142,7 @@ <td class="label"> <&|/l&>Cc</&>: </td> -<td class="value" colspan="5"><& /Elements/EmailInput, Name => 'Cc', Size => undef, Default => $ARGS{Cc} &></td> +<td class="value" colspan="5"><& /Elements/EmailInput, Name => 'Cc', Size => undef, Default => $ARGS{Cc}, AutocompleteMultiple => 1 &></td> </tr> <tr> @@ -145,7 +158,7 @@ <td class="label"> <&|/l&>Admin Cc</&>: </td> -<td class="value" colspan="5"><& /Elements/EmailInput, Name => 'AdminCc', Size => undef, Default => $ARGS{AdminCc} &></td> +<td class="value" colspan="5"><& /Elements/EmailInput, Name => 'AdminCc', Size => undef, Default => $ARGS{AdminCc}, AutocompleteMultiple => 1 &></td> </tr> <tr> @@ -157,6 +170,15 @@ </td> </tr> +<& /Elements/EditCustomFields, + %ARGS, + Object => $ticket, + CustomFields => $QueueObj->TicketCustomFields, + Grouping => 'People', + InTable => 1, + KeepValue => 1, +&> + <tr> <td class="label"> <&|/l&>Subject</&>: @@ -169,7 +191,7 @@ % if ( $gnupg_widget ) { <tr><td> </td><td colspan="5"> -<& /Elements/GnuPG/SignEncryptWidget, self => $gnupg_widget, QueueObj => $QueueObj &> +<& /Elements/Crypt/SignEncryptWidget, self => $gnupg_widget, QueueObj => $QueueObj &> </td></tr> % } @@ -204,9 +226,9 @@ <tr> <td width="50%" valign="top" class="boxcontainer"> <div class="ticket-info-basics"> - <&| /Widgets/TitleBox, title => loc('The Basics'), - title_class=> 'inverse', - color => "#993333" &> + <&| /Widgets/TitleBox, title => loc('The Basics'), + title_class=> 'inverse', + color => "#993333" &> <table border="0"> <tr><td class="label"><&|/l&>Priority</&>:</td> <td><& /Elements/SelectPriority, @@ -220,29 +242,37 @@ &></td></tr> <tr><td class="label"><&|/l&>Time Estimated</&>:</td> <td> -<& /Elements/EditTimeValue, Name => 'TimeEstimated', Default => $ARGS{TimeEstimated} || '', InUnits => $ARGS{'TimeEstimated-TimeUnits'} &> +<& /Elements/EditTimeValue, Name => 'TimeEstimated', Default => $ARGS{TimeEstimated} || '' &> </td></tr> <tr><td class="label"><&|/l&>Time Worked</&>:</td> <td> -<& /Elements/EditTimeValue, Name => 'TimeWorked', Default => $ARGS{TimeWorked} || '', InUnits => $ARGS{'TimeWorked-TimeUnits'} &> +<& /Elements/EditTimeValue, Name => 'TimeWorked', Default => $ARGS{TimeWorked} || '' &> </td></tr> <tr> <td class="label"><&|/l&>Time Left</&>:</td> <td> -<& /Elements/EditTimeValue, Name => 'TimeLeft', Default => $ARGS{TimeLeft} || '', InUnits => $ARGS{'TimeLeft-TimeUnits'} &> +<& /Elements/EditTimeValue, Name => 'TimeLeft', Default => $ARGS{TimeLeft} || '' &> </td></tr> </table> </&> <br /> <div class="ticket-info-dates"> <&|/Widgets/TitleBox, title => loc("Dates"), - title_class=> 'inverse', - color => "#663366" &> + title_class=> 'inverse', + color => "#663366" &> <table> <tr><td class="label"><&|/l&>Starts</&>:</td><td><& /Elements/SelectDate, Name => "Starts", Default => $ARGS{Starts} || '' &></td></tr> <tr><td class="label"><&|/l&>Due</&>:</td><td><& /Elements/SelectDate, Name => "Due", Default => $ARGS{Due} || '' &></td></tr> +<& /Elements/EditCustomFields, + %ARGS, + Object => $ticket, + CustomFields => $QueueObj->TicketCustomFields, + Grouping => 'Dates', + InTable => 1, + KeepValue => 1, +&> </table> </&> </div> @@ -254,17 +284,11 @@ <div class="ticket-info-links"> <&| /Widgets/TitleBox, title => loc('Links'), title_class=> 'inverse' &> -<em><&|/l&>(Enter ticket ids or URLs, separated with spaces)</&></em> -<table border="0"> -<tr><td class="label"><&|/l&>Depends on</&></td><td><input size="10" name="new-DependsOn" value="<% $ARGS{'new-DependsOn'} || '' %>" /></td></tr> -<tr><td class="label"><&|/l&>Depended on by</&></td><td><input size="10" name="DependsOn-new" value="<% $ARGS{'DependsOn-new'} || '' %>" /></td></tr> -<tr><td class="label"><&|/l&>Parents</&></td><td><input size="10" name="new-MemberOf" value="<% $ARGS{'new-MemberOf'} || '' %>" /></td></tr> -<tr><td class="label"><&|/l&>Children</&></td><td><input size="10" name="MemberOf-new" value="<% $ARGS{'MemberOf-new'} || '' %>" /></td></tr> -<tr><td class="label"><&|/l&>Refers to</&></td><td><input size="10" name="new-RefersTo" value="<% $ARGS{'new-RefersTo'} || '' %>" /></td></tr> -<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> +<& /Elements/AddLinks, + Object => $ticket, + CustomFields => $QueueObj->TicketCustomFields, + ARGSRef => \%ARGS, + &> </&> </div> <br /> @@ -281,6 +305,8 @@ $m->callback( CallbackName => "Init", ARGSRef => \%ARGS ); my $Queue = $ARGS{Queue}; $session{DefaultQueue} = $Queue; +my $current_user = $session{'CurrentUser'}; + if ($CloneTicket) { my $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} ); $CloneTicketObj->Load($CloneTicket) @@ -298,12 +324,9 @@ if ($CloneTicket) { # not TimeWorked, TimeEstimated, or TimeLeft $clone->{$_} = $CloneTicketObj->$_->AsString - for grep { $CloneTicketObj->$_->Unix } + for grep { $CloneTicketObj->$_->IsSet } map { $_ . "Obj" } qw/Starts Started Due Resolved/; - my $members = $CloneTicketObj->Members; - my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by ); - my $refers = $CloneTicketObj->RefersTo; my $get_link_value = sub { my ($link, $type) = @_; my $uri_method = $type . 'URI'; @@ -316,6 +339,8 @@ if ($CloneTicket) { return $link->$local_method || $uri->URI; }; + my (@refers, @refers_by); + my $refers = $CloneTicketObj->RefersTo; while ( my $refer = $refers->Next ) { my $refer_value = $get_link_value->($refer, 'Target'); push @refers, $refer_value if defined $refer_value; @@ -340,10 +365,10 @@ if ($CloneTicket) { } if ( @cf_values > 1 && $cf->Type eq 'Select' ) { - $clone->{"Object-RT::Ticket--CustomField-$cf_id-Value"} = \@cf_values; + $clone->{GetCustomFieldInputName( CustomField => $cf )} = \@cf_values; } else { - $clone->{"Object-RT::Ticket--CustomField-$cf_id-Value"} = join "\n", + $clone->{GetCustomFieldInputName( CustomField => $cf )} = join "\n", @cf_values; } } @@ -368,34 +393,42 @@ my @results; my $title = loc("Create a new ticket"); -my $QueueObj = RT::Queue->new($session{'CurrentUser'}); -$QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded.")); +my $QueueObj = RT::Queue->new($current_user); +$QueueObj->Load($Queue) || Abort(loc("Queue [_1] could not be loaded.", $Queue||'')); $m->callback( QueueObj => $QueueObj, title => \$title, results => \@results, ARGSRef => \%ARGS ); -$QueueObj->Disabled && Abort(loc("Cannot create tickets in a disabled queue.")); +$m->scomp( '/Articles/Elements/SubjectOverride', ARGSRef => \%ARGS, QueueObj => $QueueObj, results => \@results ); -my $CFs = $QueueObj->TicketCustomFields(); +$QueueObj->Disabled && Abort(loc("Cannot create tickets in a disabled queue.")); -my $ValidCFs = $m->comp( - '/Elements/ValidateCustomFields', - CustomFields => $CFs, - ARGSRef => \%ARGS -); +my $ticket = RT::Ticket->new($current_user); # empty ticket object ProcessAttachments(ARGSRef => \%ARGS); my $checks_failure = 0; -my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS ); -$m->comp( '/Elements/GnuPG/SignEncryptWidget:Process', +{ + my ($status, @msg) = $m->comp( + '/Elements/ValidateCustomFields', + CustomFields => $QueueObj->TicketCustomFields, + ARGSRef => \%ARGS + ); + unless ($status) { + $checks_failure = 1; + push @results, @msg; + } +} + +my $gnupg_widget = $m->comp('/Elements/Crypt/SignEncryptWidget:new', Arguments => \%ARGS ); +$m->comp( '/Elements/Crypt/SignEncryptWidget:Process', self => $gnupg_widget, QueueObj => $QueueObj, ); if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) { - my $status = $m->comp('/Elements/GnuPG/SignEncryptWidget:Check', + my $status = $m->comp('/Elements/Crypt/SignEncryptWidget:Check', self => $gnupg_widget, Operation => 'Create', QueueObj => $QueueObj, @@ -427,7 +460,7 @@ $m->comp( '/Articles/Elements/CheckSkipCreate', ARGSRef => \%ARGS, 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 ) { + if ( !$checks_failure && !$skip_create ) { # CREATE THE TICKET. # For some reason it's done by a Mason component named "Display.html" # and the call is buried in obscure error-handling stuff. @@ -443,13 +476,6 @@ if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} e $RT::Logger->crit("After display call; error is $@"); $m->abort(); } - elsif ( !$ValidCFs ) { - # Invalid CFs - while (my $CF = $CFs->Next) { - my $msg = $m->notes('InvalidField-' . $CF->Id) or next; - push @results, $CF->Name . ': ' . $msg; - } - } } 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>]); diff --git a/rt/share/html/Ticket/GnuPG.html b/rt/share/html/Ticket/Crypt.html index 9ea840f..0eb0b15 100644 --- a/rt/share/html/Ticket/GnuPG.html +++ b/rt/share/html/Ticket/Crypt.html @@ -78,7 +78,7 @@ my $encrypted = 0; my $attachments = $txn->Attachments; while ( my $attachment = $attachments->Next ) { - next unless $attachment->ContentType =~ m{^x-application-rt/gpg-encrypted\b}; + next unless $attachment->ContentType =~ m{^x-application-rt/[^-]+-encrypted\b}; $encrypted = 1; last; } diff --git a/rt/share/html/Ticket/Display.html b/rt/share/html/Ticket/Display.html index 3c2385a..41684c5 100755 --- a/rt/share/html/Ticket/Display.html +++ b/rt/share/html/Ticket/Display.html @@ -54,6 +54,7 @@ <& /Elements/ListActions, actions => \@Actions &> <& Elements/ShowUpdateStatus, Ticket => $TicketObj &> +<& Elements/ShowDependencyStatus, Ticket => $TicketObj &> % $m->callback( %ARGS, Ticket => $TicketObj, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowSummary' ); <div class="summary"> @@ -65,16 +66,21 @@ % $m->callback( Ticket => $TicketObj, %ARGS, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowHistory' ); -% if (not $ForceShowHistory and RT->Config->Get( 'DeferTransactionLoading', $session{'CurrentUser'} )) { +% my $ShowHistory = RT->Config->Get("ShowHistory", $session{'CurrentUser'}); +% if ($ShowHistory eq "delay") { + <& /Ticket/Elements/DelayShowHistory, + Ticket => $TicketObj, + ShowHeaders => $ARGS{'ShowHeaders'}, + &> +% } elsif (not $ForceShowHistory and $ShowHistory eq "click") { <& /Ticket/Elements/ClickToShowHistory, Ticket => $TicketObj, + ShowHeaders => $ARGS{'ShowHeaders'}, &> % } else { - <& /Ticket/Elements/ShowHistory , - Ticket => $TicketObj, - Tickets => $Tickets, + <& /Elements/ShowHistory , + Object => $TicketObj, Transactions => $transactions, - Collapsed => $ARGS{'Collapsed'}, ShowHeaders => $ARGS{'ShowHeaders'}, Attachments => $attachments, AttachmentContent => $attachment_content @@ -92,7 +98,6 @@ $id => undef $TicketObj => undef $ShowHeaders => 0 -$Collapsed => undef $ForceShowHistory => 0 </%ARGS> @@ -107,7 +112,7 @@ if ( ! $ARGS{'NoRedirect'} && RT::Interface::Web->MobileClient()) { } -my (@Actions, $Tickets, $title); +my (@Actions, $title); unless ($id || $TicketObj) { @@ -115,7 +120,7 @@ unless ($id || $TicketObj) { } if ($ARGS{'id'} eq 'new') { - # {{{ Create a new ticket + # Create a new ticket # Massage customer IDs into member links. my @cust_uris = map { @@ -135,10 +140,7 @@ if ($ARGS{'id'} eq 'new') { Abort('You have no permission to create tickets in that queue.'); } - ($TicketObj, @Actions) = CreateTicket( - Attachments => delete $session{'Attachments'}, - %ARGS, - ); + ($TicketObj, @Actions) = CreateTicket( %ARGS ); unless ( $TicketObj->CurrentUserHasRight('ShowTicket') ) { Abort("No permission to view newly created ticket #".$TicketObj->id."."); } @@ -150,7 +152,7 @@ if ($ARGS{'id'} eq 'new') { my $SkipProcessing; $m->callback( CallbackName => 'BeforeProcessArguments', - TicketObj => $TicketObj, Tickets => $Tickets, + TicketObj => $TicketObj, ActionsRef => \@Actions, ARGSRef => \%ARGS, SkipProcessing => \$SkipProcessing ); @@ -168,21 +170,18 @@ if ($ARGS{'id'} eq 'new') { ARGSRef => \%ARGS, Actions => \@Actions); - $ARGS{UpdateAttachments} = $session{'Attachments'}; - push @Actions, - ProcessUpdateMessage( + 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 ); + push @Actions, ProcessObjectCustomFieldUpdates(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 ); @@ -212,7 +211,6 @@ $title = loc("Ticket #[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject || ''); $m->callback( CallbackName => 'BeforeDisplay', TicketObj => \$TicketObj, - Tickets => \$Tickets, Actions => \@Actions, title => \$title, ARGSRef => \%ARGS, @@ -231,10 +229,9 @@ MaybeRedirectForResults( Arguments => { id => $TicketObj->id }, ); -# 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); +my $transactions = $TicketObj->SortedTransactions; +my $attachments = $TicketObj->Attachments; +my $attachment_content = $TicketObj->TextAttachments; my %link_rel; if (defined $session{'tickets'} and ($ARGS{'Query'} or $session{'CurrentSearchHash'}->{'Query'})) { diff --git a/rt/share/html/Ticket/Elements/AddAttachments b/rt/share/html/Ticket/Elements/AddAttachments index 25470eb..7c1f0b8 100644 --- a/rt/share/html/Ticket/Elements/AddAttachments +++ b/rt/share/html/Ticket/Elements/AddAttachments @@ -45,12 +45,14 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% if (exists $session{'Attachments'}) { +% if ( $attachments ) { <tr><td class="label"><&|/l&>Attached file</&>:</td> <td> <&|/l&>Check box to delete</&><br /> -% foreach my $attach_name (sort keys %{$session{'Attachments'}}) { -<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br /> +% foreach my $attach_name ( sort keys %$attachments ) { +<input type="checkbox" class="checkbox" name="DeleteAttach" value="<% $attach_name %>" id="DeleteAttach-<%$attach_name%>" /> +<label for="DeleteAttach-<%$attach_name%>"><% $attach_name %></label> +<br /> % } # end of foreach </td> </tr> @@ -59,3 +61,12 @@ <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 => 'End' ); +<%ARGS> +$Token => '' +</%ARGS> +<%INIT> +my $attachments; +if ( exists $session{'Attachments'}{ $Token } && keys %{ $session{'Attachments'}{ $Token } } ) { + $attachments = $session{'Attachments'}{ $Token }; +} +</%INIT> diff --git a/rt/share/html/Ticket/Elements/AddWatchers b/rt/share/html/Ticket/Elements/AddWatchers index 594574e..4093c26 100755 --- a/rt/share/html/Ticket/Elements/AddWatchers +++ b/rt/share/html/Ticket/Elements/AddWatchers @@ -69,7 +69,7 @@ <&|/l&>Group</&> </td></tr> % while (my $g = $Groups->Next ) { -<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-".$g->PrincipalId, Scope => 'queue' &></td><td><%$g->Name%> (<%$g->Description%>)</td></tr> +<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-".$g->PrincipalId &></td><td><%$g->Name%> (<%$g->Description%>)</td></tr> % } % } @@ -84,7 +84,7 @@ <tr><td> <&/Elements/SelectWatcherType, Name => "WatcherTypeEmail".$counter &> </td><td> -<input type="hidden" name="WatcherAddressEmail<%$counter%>" value="<%$email->address%>"> +<input type="hidden" name="WatcherAddressEmail<%$counter%>" value="<%$email->format%>"> <%$email->format%> </td></tr> % } @@ -110,24 +110,24 @@ my ($Users, $Groups); if ($UserString) { $Users = RT::Users->new($session{'CurrentUser'}); - $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp); + $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp, CASESENSITIVE => 0); $Users->LimitToPrivileged if $PrivilegedOnly; - } +} if ($GroupString) { $Groups = RT::Groups->new($session{'CurrentUser'}); - $Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined'); - $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp); - } + $Groups->LimitToUserDefinedGroups; + $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp, CASESENSITIVE => 0); +} my @extras; for my $addr ( values %{$Ticket->TransactionAddresses} ) { my $is_watcher; for my $type ( qw/Owner Requestor Cc AdminCc/ ) { - if ($Ticket->IsWatcher( Email => $addr->address, Type => $type )) { - $is_watcher = 1; - last; - } + if ($Ticket->IsWatcher( Email => $addr->address, Type => $type )) { + $is_watcher = 1; + last; + } } push @extras, $addr unless $is_watcher; } diff --git a/rt/share/html/Ticket/Elements/Bookmark b/rt/share/html/Ticket/Elements/Bookmark index bb80d3b..fa40cc1 100644 --- a/rt/share/html/Ticket/Elements/Bookmark +++ b/rt/share/html/Ticket/Elements/Bookmark @@ -46,48 +46,28 @@ %# %# END BPS TAGGED BLOCK }}} <%INIT> -my $bookmarks = $session{'CurrentUser'}->UserObj->FirstAttribute('Bookmarks'); -$bookmarks = $bookmarks->Content if $bookmarks; -$bookmarks ||= {}; +my $ticket = RT::Ticket->new( $session{'CurrentUser'} ); +$ticket->Load( $id ); -my $bookmarked = $bookmarks->{ $id }; # we still not sure if it's undef - -my @ids; -if ( $Toggle || !$bookmarked ) { - my $ticket = RT::Ticket->new( $session{'CurrentUser'} ); - $ticket->Load( $id ); - return unless $id = $ticket->id; - - @ids = ($id, $ticket->Merged); +my $is_bookmarked; +if ($Toggle) { + $is_bookmarked = $session{'CurrentUser'}->UserObj->ToggleBookmark($ticket); } - -if ( $Toggle ) { - if ( grep $bookmarks->{ $_ }, @ids ) { - delete $bookmarks->{ $_ } foreach @ids; - $bookmarked = 0; - } else { - $bookmarks->{ $id } = 1; - $bookmarked = 1; - } - $session{'CurrentUser'}->UserObj->SetAttribute( - Name => 'Bookmarks', - Content => $bookmarks, - ); -} elsif ( !$bookmarked ) { - $bookmarked = grep $bookmarks->{ $_ }, @ids; +else { + $is_bookmarked = $session{'CurrentUser'}->UserObj->HasBookmark($ticket); } </%INIT> <%ARGS> $id $Toggle => 0 </%ARGS> -<span class="toggle-bookmark-<% $id %>"> +<span class="toggle-bookmark toggle-bookmark-<% $id %>"> % my $url = RT->Config->Get('WebPath') ."/Helpers/Toggle/TicketBookmark?id=". $id; -<a align="right" href="<% $url %>" onclick="jQuery('.toggle-bookmark-'+<% $id |n,j%>).load(<% $url |n,j %>); return false;" > -% if ( $bookmarked ) { -<img src="<% RT->Config->Get('WebPath') %>/NoAuth/images/star.gif" alt="<% loc('Remove Bookmark') %>" style="border-style: none" /> +<a align="right" href="<% $url %>" onclick="jQuery.get(<% $url |n,j %>, function(data){ jQuery('.toggle-bookmark-'+<% $id |n,j%>).replaceWith(data) }); return false;" > +% if ( $is_bookmarked ) { +<img src="<% RT->Config->Get('WebPath') %>/static/images/star.gif" alt="<% loc('Remove Bookmark') %>" style="border-style: none" /> % } else { -<img src="<% RT->Config->Get('WebPath') %>/NoAuth/images/empty_star.gif" alt="<% loc('Add Bookmark') %>" style="border-style: none" /> +<img src="<% RT->Config->Get('WebPath') %>/static/images/empty_star.gif" alt="<% loc('Add Bookmark') %>" style="border-style: none" /> % } </a> </span> diff --git a/rt/share/html/Ticket/Elements/ClickToShowHistory b/rt/share/html/Ticket/Elements/ClickToShowHistory index 3b547b9..47a08f2 100644 --- a/rt/share/html/Ticket/Elements/ClickToShowHistory +++ b/rt/share/html/Ticket/Elements/ClickToShowHistory @@ -46,7 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <div id="deferred_ticket_history"> - <& /Widgets/TitleBoxStart, title => 'History' &> + <& /Widgets/TitleBoxStart, title => loc('History') &> <a href="<% $display %>" onclick="jQuery('#deferred_ticket_history').text(<% loc('Loading...') |n,j%>).load(<% $url |n,j %>); return false;" ><% loc('Show ticket history') %></a> <& /Widgets/TitleBoxEnd &> </div> @@ -54,7 +54,10 @@ $Ticket </%ARGS> <%INIT> -my $id = $Ticket->id; -my $url = RT->Config->Get('WebPath') ."/Helpers/TicketHistory?id=". $id; -my $display = RT->Config->Get('WebPath') ."/Ticket/Display.html?id=$id;ForceShowHistory=1"; +my %params = %ARGS; +delete $params{Ticket}; + +my $query = $m->comp('/Elements/QueryString', %params, id => $Ticket->id ); +my $url = RT->Config->Get('WebPath')."/Helpers/TicketHistory?$query"; +my $display = RT->Config->Get('WebPath')."/Ticket/Display.html?ForceShowHistory=1;$query"; </%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowUserEntry b/rt/share/html/Ticket/Elements/DelayShowHistory index a589168..a675fe2 100644 --- a/rt/share/html/Ticket/Elements/ShowUserEntry +++ b/rt/share/html/Ticket/Elements/DelayShowHistory @@ -45,12 +45,34 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Elements/ShowUser, %ARGS &> -% if ($Ticket and grep { $_->Content eq $User->EmailAddress } $Ticket->SquelchMailTo) { -<b><&|/l&>(Will not be sent email)</&></b> -% } - +<div id="delayed_ticket_history"> + <& /Widgets/TitleBoxStart, title => loc('History') &> + <&|/l&>Loading...</&> + <& /Widgets/TitleBoxEnd &> +</div> +<script type="text/javascript"> +jQuery(function(){ + jQuery('#delayed_ticket_history').load(<% $url |n %>, null, function() { + jQuery(this).find('.titlebox-content').hide().slideDown(400, function(){ + // Jump to any anchor specified after we load the txns into the page + var hash = window.location.hash; + if (hash) { + window.location.hash = ""; // trick the browser into a "change" + window.location.hash = hash; + } + }); + }); +}); +</script> <%ARGS> -$User => undef -$Ticket => undef +$Ticket </%ARGS> +<%INIT> +my %params = %ARGS; +delete $params{Ticket}; + +my $url = JSON( + RT->Config->Get('WebPath') . "/Helpers/TicketHistory?". + $m->comp('/Elements/QueryString', %params, id => $Ticket->id ) +); +</%INIT> diff --git a/rt/share/html/Ticket/Elements/EditBasics b/rt/share/html/Ticket/Elements/EditBasics index a54caac..d6f1862 100755 --- a/rt/share/html/Ticket/Elements/EditBasics +++ b/rt/share/html/Ticket/Elements/EditBasics @@ -60,13 +60,12 @@ unless ( @fields ) { html => '<input name="Subject" value="'.(defined($subject) ? $m->interp->apply_escapes( $subject, 'h' ) : '').'" />', }, { name => 'Status', - comp => '/Elements/SelectStatus', + comp => '/Ticket/Elements/SelectStatus', args => { Name => 'Status', - DefaultLabel => loc("[_1] (Unchanged)",loc($TicketObj->Status)), - Default => $defaults{'Status'} || undef, + Default => $defaults{'Status'}, + DefaultFromArgs => 0, TicketObj => $TicketObj, - QueueObj => $TicketObj->QueueObj, onchange => 'changeStatus()', }, }, @@ -148,7 +147,7 @@ for my $field (@fields) { % } % for my $field (@fields) { <tr class="<% lc $field->{'name'} %>">\ -<td class="label"><&|/l&><% $field->{'name'} %></&>:</td>\ +<td class="label"><% loc($field->{'name'}) %>:</td>\ <td class="value"><% $field->{'html'} |n %></td>\ </tr> % } diff --git a/rt/share/html/Ticket/Elements/EditCustomFields b/rt/share/html/Ticket/Elements/EditCustomFields index 5f17d18..336e86c 100755 --- a/rt/share/html/Ticket/Elements/EditCustomFields +++ b/rt/share/html/Ticket/Elements/EditCustomFields @@ -45,63 +45,17 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% $m->callback( %ARGS, CallbackName => 'BeforeCustomFields' ); -% if ( $WRAP ) { -<<% $WRAP %> class="edit-custom-fields"> -% } -% while ( my $CustomField = $CustomFields->Next ) { -% next unless $CustomField->CurrentUserHasRight('ModifyCustomField'); -% 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, - %ARGS, - Object => $TicketObj, - CustomField => $CustomField, - NamePrefix => $NamePrefix, - Default => $default, - &> -% if (my $msg = $m->notes('InvalidField-' . $CustomField->Id)) { - <br /> - <span class="cfinvalidfield"><% $msg %></span> -% } - </<% $CELL %>> - </<% $FIELD %>> -% } - -% if ( $WRAP ) { -</<% $WRAP %>> -% } -% $m->callback( %ARGS, CallbackName => 'AfterCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj ); <%INIT> -my $CustomFields; +RT->Deprecated( Remove => "4.4", Instead => "/Elements/EditCustomFields" ); +my $CustomFields; if ($TicketObj && !$OnCreate) { - $CustomFields = $TicketObj->CustomFields(); - $NamePrefix .= "Object-RT::Ticket-".$TicketObj->Id."-CustomField-"; + $CustomFields = $TicketObj->CustomFields; } else { - $CustomFields = $QueueObj->TicketCustomFields(); - $NamePrefix .= "Object-RT::Ticket--CustomField-"; + $CustomFields = $QueueObj->TicketCustomFields; } - $m->callback( %ARGS, CallbackName => 'MassageCustomFields', 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'; -} - # show hints for missing required fields if ( $TicketObj ) { foreach my $field ( $TicketObj->MissingRequiredFields ) { @@ -109,13 +63,14 @@ if ( $TicketObj ) { } } +return $m->comp('/Elements/EditCustomFields', + %ARGS, + Object => $TicketObj || RT::Ticket->new( $session{'CurrentUser'} ), + CustomFields => $CustomFields, +); </%INIT> <%ARGS> -$NamePrefix => '' $TicketObj => undef $QueueObj => undef $OnCreate => undef -$DefaultsFromTopArguments => 1 -$AsTable => 0 -$InTable => 0 </%ARGS> diff --git a/rt/share/html/Ticket/Elements/EditDates b/rt/share/html/Ticket/Elements/EditDates index 7793a8a..710ee51 100755 --- a/rt/share/html/Ticket/Elements/EditDates +++ b/rt/share/html/Ticket/Elements/EditDates @@ -76,6 +76,7 @@ <& /Elements/SelectDate, menu_prefix => 'WillResolve', current => 0 &> (<% $TicketObj->WillResolveObj->AsString %>) </td> </tr> + <& /Elements/EditCustomFields, Object => $TicketObj, Grouping => 'Dates', InTable => 1 &> % $m->callback( %ARGS, CallbackName => 'EndOfList', Ticket => $TicketObj ); </table> <%ARGS> diff --git a/rt/share/html/Ticket/Elements/FindTransactions b/rt/share/html/Ticket/Elements/EditMerge index 950320e..321a6f4 100644 --- a/rt/share/html/Ticket/Elements/FindTransactions +++ b/rt/share/html/Ticket/Elements/EditMerge @@ -45,28 +45,35 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} +<i> +<&|/l&>Warning: merging is a non-reversible action! Enter a single ticket number to be merged into.</&> +</i> + +<table> + <tr> + <td class="label"><&|/l&>Merge into</&>:</td> + <td class="entry"><input name="<% $Name %>" value="<% $Default || '' %>" data-autocomplete="Tickets" data-autocomplete-exclude="<% join( ' ', @excludes) || '' %>" /></td> + </tr> +</table> + <%INIT> -my $Transactions = RT::Transactions->new($session{'CurrentUser'}); -if ($Tickets) { - while (my $t = $Tickets->Next) { - $Transactions->LimitToTicket($t->id); +my @excludes; +if ( $Ticket ) { + $Name ||= $Ticket->id . '-MergeInto'; + @excludes = $Ticket->id; +} +elsif ( $Tickets ) { + $Name ||= 'Ticket-MergeInto'; + while ( my $ticket = $Tickets->Next ) { + push @excludes, $ticket->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 }, - ); -$Transactions->Next(); $Transactions->GotoFirstItem(); # actually do the search -return ($Transactions); +$Default ||= $ARGS{$Name}; </%INIT> + <%ARGS> $Ticket => undef $Tickets => undef +$Name => '' +$Default => '' </%ARGS> diff --git a/rt/share/html/Ticket/Elements/EditPeople b/rt/share/html/Ticket/Elements/EditPeople index c5edb9c..8d5a418 100755 --- a/rt/share/html/Ticket/Elements/EditPeople +++ b/rt/share/html/Ticket/Elements/EditPeople @@ -60,23 +60,35 @@ <& AddWatchers, Ticket => $Ticket, UserString => $UserString, UserOp => $UserOp, UserField => $UserField, - GroupString => $GroupString, GroupOp => $GroupOp, - GroupField => $GroupField, PrivilegedOnly => $PrivilegedOnly &> + GroupString => $GroupString, GroupOp => $GroupOp, + GroupField => $GroupField, PrivilegedOnly => $PrivilegedOnly &> </td><td valign="top"> <h3><&|/l&>Owner</&></h3> <&|/l&>Owner</&>: <& /Elements/SelectOwner, Name => 'Owner', QueueObj => $Ticket->QueueObj, TicketObj => $Ticket, Default => $Ticket->OwnerObj->Id, DefaultValue => 0&> <h3><&|/l&>Current watchers</&></h3> +<i><&|/l&>(Check box to delete)</&></i><br /> -<&|/l&>Requestors</&>: -<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Requestors &> +<table> -<&|/l&>Cc</&>: -<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Cc &> +<tr> + <td class="label"><&|/l&>Requestors</&>:</td> + <td class="value"><& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Requestors &></td> +</tr> -<&|/l&>Administrative Cc</&>: -<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->AdminCc &> +<tr> + <td class="label"><&|/l&>Cc</&>:</td> + <td class="value"><& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Cc &></td> +</tr> + +<tr> + <td class="label"><&|/l&>Administrative Cc</&>:</td> + <td class="value"><& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->AdminCc &></td> +</tr> + +<& /Elements/EditCustomFields, Object => $Ticket, Grouping => 'People', InTable => 1 &> + +</table> -<i><&|/l&>(Check box to delete)</&></i><br /> </td> </tr> </table> diff --git a/rt/share/html/Ticket/Elements/EditTransactionCustomFields b/rt/share/html/Ticket/Elements/EditTransactionCustomFields index 4de7e5f..f0c1f29 100644 --- a/rt/share/html/Ticket/Elements/EditTransactionCustomFields +++ b/rt/share/html/Ticket/Elements/EditTransactionCustomFields @@ -45,7 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -% $m->callback( CallbackName => 'BeforeTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, NamePrefix => $NamePrefix ); +% $m->callback( CallbackName => 'BeforeTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, InTable => $InTable ); % if ( $WRAP ) { <<% $WRAP %> class="edit-transaction-custom-fields"> % } @@ -56,7 +56,7 @@ % next unless $CF->UILocation eq $UILocation; <<% $FIELD %>> <<% $CELL %> class="label cflabel"> - <span class="name"><% loc($CF->Name) %>:</span><br /> + <span class="name"><% $CF->Name %>:</span><br /> % if ( $CF->Type ne 'TimeValue' ) { <span class="type"><% $CF->FriendlyType %></span> % } @@ -65,7 +65,7 @@ <& /Elements/EditCustomField, %ARGS, CustomField => $CF, - NamePrefix => $NamePrefix, + Object => RT::Transaction->new( $session{'CurrentUser'} ), &> % if (my $msg = $m->notes('InvalidField-' . $CF->Id)) { <br /> @@ -78,7 +78,7 @@ % if ( $WRAP ) { </<% $WRAP %>> % } -% $m->callback( CallbackName => 'AfterTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, NamePrefix => $NamePrefix ); +% $m->callback( CallbackName => 'AfterTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, InTable => $InTable ); <%INIT> my $CustomFields; @@ -89,7 +89,7 @@ if ($TicketObj) { $CustomFields = $QueueObj->TicketTransactionCustomFields(); } -$m->callback( CallbackName => 'MassageTransactionCustomFields', CustomFields => $CustomFields ); +$m->callback( CallbackName => 'MassageTransactionCustomFields', CustomFields => $CustomFields, InTable => $InTable ); $AsTable ||= $InTable; my $FIELD = $AsTable ? 'tr' : 'div'; @@ -103,7 +103,6 @@ if ( $AsTable ) { </%INIT> <%ARGS> -$NamePrefix => "Object-RT::Transaction--CustomField-" $TicketObj => undef $QueueObj => undef $AsTable => 0 diff --git a/rt/share/html/Ticket/Elements/EditWatchers b/rt/share/html/Ticket/Elements/EditWatchers index ab5ada3..0f613ca 100755 --- a/rt/share/html/Ticket/Elements/EditWatchers +++ b/rt/share/html/Ticket/Elements/EditWatchers @@ -55,7 +55,7 @@ % while ( my $watcher = $Members->Next ) { % my $member = $watcher->MemberObj->Object; <li> -<input type="checkbox" class="checkbox" name="Ticket-DeleteWatcher-Type-<% $Watchers->Type %>-Principal-<% $watcher->MemberId %>" value="1" unchecked /> +<input type="checkbox" class="checkbox" name="Ticket-DeleteWatcher-Type-<% $Watchers->Name %>-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 ) ) { diff --git a/rt/share/html/Ticket/Elements/FindAttachments b/rt/share/html/Ticket/Elements/FindAttachments deleted file mode 100644 index 448df07..0000000 --- a/rt/share/html/Ticket/Elements/FindAttachments +++ /dev/null @@ -1,95 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<%INIT> -my %documents; - -#A default implementation here loops through all transactions and pulls out all their attachments. -# We end up doing an end-run around that to get a bit more performance - -# We force the cache of ticket transactions to get populated up front. otherwise, the -# code that looks at attachments will look at each one in turn. -my $attachments = RT::Attachments->new( $session{'CurrentUser'} ); - -$attachments->Columns( qw( Id Filename Headers Subject Parent ContentEncoding ContentType TransactionId Created)); - -my $transactions = $attachments->NewAlias('Transactions'); -$attachments->Join( ALIAS1 => 'main', - FIELD1 => 'TransactionId', - ALIAS2 => $transactions, - FIELD2 => 'id' ); - -my $tickets = $attachments->NewAlias('Tickets'); - - $attachments->Join( ALIAS1 => $transactions, - FIELD1 => 'ObjectId', - ALIAS2 => $tickets, - FIELD2 => 'id' ); - - $attachments->Limit( ALIAS => $transactions, - FIELD => 'ObjectType', - VALUE => 'RT::Ticket'); -if ($Tickets) { - while ($Ticket = $Tickets->Next) { - $attachments->Limit( ALIAS => $tickets, - FIELD => 'EffectiveId', - VALUE => $Ticket->id() ); - } -} else { - $attachments->Limit( ALIAS => $tickets, - FIELD => 'EffectiveId', - VALUE => $Ticket->id() ); -} - - -return ($attachments); -</%INIT> -<%ARGS> -$Ticket => undef -$Tickets => undef -</%ARGS> - diff --git a/rt/share/html/Ticket/Elements/FoldStanzaJS b/rt/share/html/Ticket/Elements/FoldStanzaJS deleted file mode 100644 index 806bce9..0000000 --- a/rt/share/html/Ticket/Elements/FoldStanzaJS +++ /dev/null @@ -1,50 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<span - class="message-stanza-folder closed" - onclick="fold_message_stanza(this, <%loc('Show quoted text') |n,j%>, <%loc('Hide quoted text') |n,j%>);"><%loc('Show quoted text')%></span><br />\ diff --git a/rt/share/html/Ticket/Elements/LoadTextAttachments b/rt/share/html/Ticket/Elements/LoadTextAttachments index 5e87c64..69ec52b 100644 --- a/rt/share/html/Ticket/Elements/LoadTextAttachments +++ b/rt/share/html/Ticket/Elements/LoadTextAttachments @@ -46,48 +46,9 @@ %# %# END BPS TAGGED BLOCK }}} <%INIT> - -my $attachments = RT::Attachments->new( $session{'CurrentUser'} ); - -$attachments->Columns( qw(id Content ContentType TransactionId ContentEncoding)); - -if ( $Ticket->CurrentUserHasRight('ShowTicket') ) { - my $transactions = $attachments->NewAlias('Transactions'); - $attachments->Join( ALIAS1 => 'main', - FIELD1 => 'TransactionId', - ALIAS2 => $transactions, - FIELD2 => 'id' ); - - my $tickets = $attachments->NewAlias('Tickets'); - - - $attachments->Join( ALIAS1 => $transactions, - FIELD1 => 'ObjectId', - ALIAS2 => $tickets, - FIELD2 => 'id' ); - - $attachments->Limit( ALIAS => $transactions, - FIELD => 'ObjectType', - VALUE => 'RT::Ticket'); - - - $attachments->Limit( ALIAS => $tickets, - FIELD => 'EffectiveId', - VALUE => $Ticket->id() ); - # if the user may not see comments do not return them - unless ( $Ticket->CurrentUserHasRight('ShowTicketComments') ) { - $attachments->Limit( ALIAS => $transactions, FIELD => 'Type', OPERATOR => '!=', VALUE => "Comment" ); - } - - $attachments->Limit ( FIELD => 'ContentType', OPERATOR => '=', VALUE => 'text/plain'); - $attachments->Limit ( FIELD => 'ContentType', OPERATOR => 'STARTSWITH', VALUE => 'message/'); - $attachments->Limit ( FIELD => 'ContentType', OPERATOR => '=', VALUE => 'text'); - $attachments->Limit ( FIELD => 'Filename', OPERATOR => 'IS', VALUE => 'NULL') - if RT->Config->Get('SuppressInlineTextFiles', $Ticket->CurrentUser ); -} -return ($attachments); +RT->Deprecated( Remove => "4.4", Instead => "RT::Ticket->TextAttachments" ); +return $Ticket->TextAttachments; </%INIT> <%ARGS> -$Ticket => undef +$Ticket </%ARGS> - diff --git a/rt/share/html/Ticket/Elements/PreviewScrips b/rt/share/html/Ticket/Elements/PreviewScrips index bb51ef3..cc55fa8 100755 --- a/rt/share/html/Ticket/Elements/PreviewScrips +++ b/rt/share/html/Ticket/Elements/PreviewScrips @@ -69,7 +69,7 @@ my %squelched = ProcessTransactionSquelching( \%ARGS ); % @{$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]</&> + <&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->Template)&>[_1] [_2] with template [_3]</&> <br /> % for my $type (qw(To Cc Bcc)) { % my @addresses = $scrip->ActionObj->Action->$type(); @@ -88,31 +88,7 @@ my %squelched = ProcessTransactionSquelching( \%ARGS ); </ul> % } % if (RT->Config->Get('PreviewScripMessages')) { - <textarea cols="80" rows="5"><% Encode::decode( "UTF-8", $scrip->ActionObj->TemplateObj->MIMEObj->as_string ) %></textarea> -% } - <br /> -% } -% } - -% 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 = not $squelched{$address}; -% $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> + <textarea cols="80" rows="5"><% Encode::decode( "UTF-8", $scrip->ActionObj->Action->TemplateObj->MIMEObj->as_string )%></textarea> % } <br /> % } diff --git a/rt/share/html/Ticket/Elements/Reminders b/rt/share/html/Ticket/Elements/Reminders index 1ce2d18..80326db 100644 --- a/rt/share/html/Ticket/Elements/Reminders +++ b/rt/share/html/Ticket/Elements/Reminders @@ -50,11 +50,12 @@ $Ticket => undef $id => undef $ShowCompleted => 0 $Edit => 0 +$ShowSave => 1 </%args> <%init> $Ticket = LoadTicket($id) if ($id); -my $resolve_status = $Ticket->QueueObj->Lifecycle->ReminderStatusOnResolve; +my $resolve_status = $Ticket->LifecycleObj->ReminderStatusOnResolve; my $count_reminders = RT::Reminders->new($session{'CurrentUser'}); $count_reminders->Ticket($Ticket->id); @@ -67,10 +68,10 @@ my $has_reminders = $count_tickets->Count; # We've made changes, let's reload our search my $reminder_collection = $count_reminders->Collection; -my $visible = 0; </%init> <input type="hidden" class="hidden" name="id" value="<% $Ticket->id %>" /> <input type="hidden" class="hidden" name="update-reminders" value="1" /> +% my $editable = 0; % if ($has_reminders) { <table border="0" cellpadding="1" cellspacing="0" class="collection-as-table"<% $Edit ? ' style="width: auto;"' : '' |n %>> <tr> @@ -89,16 +90,18 @@ my $visible = 0; % if ( $reminder->Status eq $resolve_status && !$ShowCompleted ) { <tr class="hidden"><td><input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /></td></tr> % $i++; -% } elsif ($Edit) { +% } +% else { +% $editable = 1 if !$editable && $reminder->CurrentUserHasRight( 'ModifyTicket' ); +% if ($Edit) { <& SELF:EditEntry, Reminder => $reminder, Ticket => $Ticket, Index => $i &> -% $visible++; -% } else { +% } else { <& SELF:ShowEntry, Reminder => $reminder, Ticket => $Ticket, Index => $i &> -% $visible++; +% } % } % } </table> -% if ( $visible > 0 ) { +% if ( $editable ) { <i><&|/l&>(Check box to complete)</&></i><br /><br /> % } % } else { @@ -112,11 +115,15 @@ my $visible = 0; % } % } -% if (lc $Ticket->Status ne "deleted") { +% if (lc $Ticket->Status ne "deleted" and $Ticket->QueueObj->CurrentUserHasRight('CreateTicket') and $Ticket->CurrentUserHasRight('ModifyTicket') ) { <&|/l&>New reminder:</&> <& SELF:NewReminder, Ticket => $Ticket &> +% $editable = 1; +% } + +% if ( $editable && $ShowSave ) { +<div align="right"><input type="submit" class="button" value="<&|/l&>Save</&>" /></div> % } -% return(lc $Ticket->Status ne "deleted" or $visible); <%method NewReminder> <%args> $Ticket @@ -142,17 +149,38 @@ $Reminder $Ticket $Index </%args> -<tr class="<% $Index%2 ? 'oddline' : 'evenline' %>"> -<td class="entry"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->QueueObj->Lifecycle->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> /></td> +<tr class="<% $Index%2 ? 'oddline' : 'evenline' %>" id="reminder-<% $Reminder->id %>"> +<td class="entry"> +% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { +<input name="Complete-Reminder-<% $Reminder->id %>" type="hidden" +value=<% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 1 : 0 %> /> +% } + +<input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> +% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { +disabled="disabled" +% } +/></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> +<td class="entry" colspan="3"> +<input type="text" size="50" name="Reminder-Subject-<% $Reminder->id %>" value="<% $Reminder->Subject %>" +% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { +readonly="readonly" +% } +/> +</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> +<td class="entry"> +% if ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { +<& /Elements/SelectDate, Name => 'Reminder-Due-'.$Reminder->id &> +% } +(<% $Reminder->DueObj->AsString %>) +</td> </tr> </%method> <%method ShowEntry> @@ -162,10 +190,20 @@ $Ticket $Index </%args> % 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 $Reminder->QueueObj->Lifecycle->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> /></td> -<td class="collection-as-table"><% $Reminder->Subject %></td> +% my $overdue = $dueobj->IsSet && $dueobj->Diff < 0 ? 1 : 0; +<tr class="<% $Index%2 ? 'oddline' : 'evenline' %>" id="reminder-<% $Reminder->id %>"> + +<td class="collection-as-table"> +% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { +<input name="Complete-Reminder-<% $Reminder->id %>" type="hidden" +value=<% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 1 : 0 %> /> +% } +<input type="checkbox" value="1" id="Complete-Reminder-<% $Reminder->id %>" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> +% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { +disabled="disabled" +% } +/></td> +<td class="collection-as-table"><label for="Complete-Reminder-<% $Reminder->id %>"><% $Reminder->Subject %></label></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> diff --git a/rt/share/html/Ticket/Elements/ShowDependencies b/rt/share/html/Ticket/Elements/SelectStatus index 72e37b1..f793967 100755..100644 --- a/rt/share/html/Ticket/Elements/ShowDependencies +++ b/rt/share/html/Ticket/Elements/SelectStatus @@ -45,22 +45,39 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<&|/l&>Depends on</&>:<br /> -% while (my $Link = $Ticket->DependsOn->Next) { -% my $member = $Link->TargetObj; -<a href="<%RT->Config->Get('WebPath')%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<& /Elements/ShowUser, User => $member->OwnerObj &>) <%$member->Subject%> - -[<%$member->Status%>] - <br /> -% } -<&|/l&>Depended on by</&>:<br /> -% while (my $Link = $Ticket->DependedOnBy->Next) { -% my $member = $Link->TargetObj; -<a href="<%RT->Config->Get('WebPath')%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<& /Elements/ShowUser, User => $member->OwnerObj &>) <%$member->Subject%> -[<%$member->Status%>] - <br /> -% } +<& /Elements/SelectStatus, + %ARGS, + Statuses => \@Statuses, + Object => $TicketObj || $QueueObj, + Lifecycles => \@Lifecycles, + Type => 'ticket', + onchange => $onchange, +&> +<%INIT> +my @Lifecycles; +for my $id (keys %Queues) { + my $queue = RT::Queue->new($session{'CurrentUser'}); + $queue->Load($id); + push @Lifecycles, $queue->LifecycleObj if $queue->id; +} +if ($TicketObj) { + $ARGS{DefaultLabel} = loc("[_1] (Unchanged)", loc($TicketObj->Status)); + if ($DefaultFromArgs and $DECODED_ARGS->{Status}) { + $ARGS{Default} = $DECODED_ARGS->{Status}; + } elsif (defined $ARGS{Default}) { + $ARGS{Default} = undef if $TicketObj->Status eq $ARGS{Default}; + } +} elsif ($QueueObj) { + $ARGS{DefaultValue} = 0; + $ARGS{Default} ||= $DECODED_ARGS->{Status} || $QueueObj->LifecycleObj->DefaultOnCreate; +} +</%INIT> <%ARGS> -$Ticket => undef +$DefaultFromArgs => 1, +@Statuses => () +$TicketObj => undef +$QueueObj => undef +%Queues => () +$onchange => undef </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowAttachments b/rt/share/html/Ticket/Elements/ShowAttachments index 5cf4531..a567844 100755 --- a/rt/share/html/Ticket/Elements/ShowAttachments +++ b/rt/share/html/Ticket/Elements/ShowAttachments @@ -56,34 +56,10 @@ <%$key%><br /> <ul> % foreach my $rev (@{$documents{$key}}) { - -<%PERL> -my $size = $rev->ContentLength; - -if ($size) { - my $kb = int($size/102.4) / 10; - my $units = RT->Config->Get('AttachmentUnits'); - - if (!defined($units)) { - if ($size > 1024) { - $size = $kb . "k"; - } - else { - $size = $size . "b"; - } - } - elsif ($units eq 'k') { - $size = $kb . "k"; - } - else { - $size = $size . "b"; - } - -</%PERL> - +% if ($rev->ContentLength) { <li><font size="-2"> <a href="<%RT->Config->Get('WebPath')%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | un %>"> -% my $desc = loc("[_1] ([_2]) by [_3]", $rev->CreatedAsString, $size, $m->scomp('/Elements/ShowUser', User => $rev->CreatorObj)); +% my $desc = loc("[_1] ([_2]) by [_3]", $rev->CreatedAsString, $rev->FriendlyContentLength, $m->scomp('/Elements/ShowUser', User => $rev->CreatorObj)); <% $desc |n%> </a> </font></li> @@ -100,8 +76,10 @@ if ($size) { # If we haven't been passed in an Attachments object (through the precaching mechanism) # then we need to find one -$Attachments ||= $m->comp('FindAttachments', Ticket => $Ticket); +$Attachments ||= $Ticket->Attachments; +# XXX PERF: why doesn't this Limit on Filename to avoid fetching *all* the +# attachments? my %documents; while ( my $attach = $Attachments->Next() ) { next unless defined $attach->Filename && length $attach->Filename; diff --git a/rt/share/html/Ticket/Elements/ShowBasics b/rt/share/html/Ticket/Elements/ShowBasics index f9ec540..546f581 100755 --- a/rt/share/html/Ticket/Elements/ShowBasics +++ b/rt/share/html/Ticket/Elements/ShowBasics @@ -60,12 +60,14 @@ <td class="value"><& ShowTime, minutes => $Ticket->TimeEstimated &></td> </tr> % } +% $m->callback( %ARGS, CallbackName => 'AfterTimeEstimated', TicketObj => $Ticket ); % if ($Ticket->TimeWorked) { <tr class="time worked"> <td class="label"><&|/l&>Worked</&>:</td> <td class="value"><& ShowTime, minutes => $Ticket->TimeWorked &></td> </tr> % } +% $m->callback( %ARGS, CallbackName => 'AfterTimeWorked', TicketObj => $Ticket ); % if ($Ticket->TimeLeft) { <tr class="time left"> <td class="label"><&|/l&>Left</&>:</td> @@ -83,8 +85,13 @@ <td class="value"><& ShowQueue, Ticket => $Ticket, QueueObj => $Ticket->QueueObj &></td> </tr> % } + <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket, Grouping => 'Basics', Table => 0 &> +% if ($UngroupedCFs) { + <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket, Grouping => '', Table => 0 &> +% } % $m->callback( %ARGS, CallbackName => 'EndOfList', TicketObj => $Ticket ); </table> <%ARGS> $Ticket => undef +$UngroupedCFs => 0 </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowCustomFields b/rt/share/html/Ticket/Elements/ShowCustomFields index 2e2276e..7d4298a 100755 --- a/rt/share/html/Ticket/Elements/ShowCustomFields +++ b/rt/share/html/Ticket/Elements/ShowCustomFields @@ -45,7 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Elements/ShowCustomFields, Object => $Ticket &> +<& /Elements/ShowCustomFields, %ARGS, Object => $Ticket &> <%ARGS> $Ticket => undef </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowDates b/rt/share/html/Ticket/Elements/ShowDates index 9a6e323..24e88e2 100755 --- a/rt/share/html/Ticket/Elements/ShowDates +++ b/rt/share/html/Ticket/Elements/ShowDates @@ -50,49 +50,74 @@ <td class="label"><&|/l&>Created</&>:</td>\ <td class="value"><% $Ticket->CreatedObj->AsString %></td> </tr> +% $m->callback( %ARGS, CallbackName => 'AfterCreated', TicketObj => $Ticket ); <tr class="date starts"> <td class="label"><&|/l&>Starts</&>:</td>\ <td class="value"><% $Ticket->StartsObj->AsString %></td> </tr> +% $m->callback( %ARGS, CallbackName => 'AfterStarts', TicketObj => $Ticket ); <tr class="date started"> <td class="label"><&|/l&>Started</&>:</td>\ <td class="value"><% $Ticket->StartedObj->AsString %></td> </tr> +% $m->callback( %ARGS, CallbackName => 'AfterStarted', TicketObj => $Ticket ); <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> +% $m->callback( %ARGS, CallbackName => 'AfterTold', TicketObj => $Ticket ); <tr class="date due"> <td class="label"><&|/l&>Due</&>:</td>\ % my $due = $Ticket->DueObj; -% if ( $due && $due->Unix > 0 && $due->Diff < 0 ) { +% if ( $due && $due->IsSet && $due->Diff < 0 && $Ticket->QueueObj->IsActiveStatus($Ticket->Status) ) { <td class="value"><span class="overdue"><% $due->AsString %></span></td> % } else { <td class="value"><% $due->AsString %></td> % } </tr> +% $m->callback( %ARGS, CallbackName => 'AfterDue', TicketObj => $Ticket ); <tr class="date resolved"> <td class="label"><&|/l&>Resolved</&>:</td>\ <td class="value"><% $Ticket->ResolvedObj->AsString %></td> </tr> +% $m->callback( %ARGS, CallbackName => 'AfterResolved', TicketObj => $Ticket ); % my $willresolve = $Ticket->WillResolveObj; % if ( $willresolve && $willresolve->Unix > 0 ) { <tr> <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 class="date updated"> +% } # 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"><a href="#lasttrans"><% $UpdatedString | n %></a></td> + <td class="value"><a href="<% $UpdatedLink %>"><% $UpdatedString | n %></a></td> % } else { <td class="value"><% $UpdatedString | n %></td> % } </tr> +% $m->callback( %ARGS, CallbackName => 'AfterUpdated', TicketObj => $Ticket ); + <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket, Grouping => 'Dates', Table => 0 &> % $m->callback( %ARGS, CallbackName => 'EndOfList', TicketObj => $Ticket ); </table> <%ARGS> $Ticket => undef $UpdatedLink => 1 </%ARGS> +<%INIT> +if ($UpdatedLink and $Ticket) { + my $txns = $Ticket->Transactions; + $txns->OrderByCols( + { FIELD => "Created", ORDER => "DESC" }, + { FIELD => "id", ORDER => "DESC" }, + ); + $txns->RowsPerPage(1); + + if (my $latest = $txns->First) { + $UpdatedLink = "#txn-" . $latest->id; + } else { + undef $UpdatedLink; + } +} +</%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowMembers b/rt/share/html/Ticket/Elements/ShowDependencyStatus index 25011ef..eba6139 100755..100644 --- a/rt/share/html/Ticket/Elements/ShowMembers +++ b/rt/share/html/Ticket/Elements/ShowDependencyStatus @@ -45,30 +45,34 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<ul> -% while (my $link = $members->Next) { -<li><& /Elements/ShowLink, URI => $link->BaseURI &><br /> -% next if $link->BaseObj and $checked->{$link->BaseObj->id}; -% if ($depth < 8) { -<& /Ticket/Elements/ShowMembers, Ticket => $link->BaseObj, depth => ($depth+1), checked => $checked &> +<div class="dependency-status"> +% if ($approvals) { + <span class="summary"> +% if ($approvals == 1) { + <&|/l&>Pending approval.</&> +% } else { + <&|/l, $approvals &>Pending [quant,_1,approval,approvals].</&> +% } + </span> + <&|/l&>This ticket cannot be resolved until it is approved.</&> +% } else { + <span class="summary"><&|/l, $depends &>Pending [quant,_1,ticket,tickets].</&></span> + <&|/l, $depends &>This ticket cannot be resolved until its [numerate,_1,dependency is,dependencies are] resolved.</&> % } -</li> -% } -</ul> - -<%INIT> - -return unless $Ticket; -my $members = $Ticket->Members; -return unless $members->Count; - -return if $checked->{$Ticket->id}; +</div> +<%args> +$Ticket +</%args> +<%init> +# normal tickets +my $deps = $Ticket->UnresolvedDependencies; +$deps->LimitType( VALUE => 'ticket' ); +my $depends = $deps->Count || 0; -$checked->{$Ticket->id} = 1; -</%INIT> +# approvals +$deps = $Ticket->UnresolvedDependencies; +$deps->LimitType( VALUE => 'approval' ); +my $approvals = $deps->Count || 0; -<%ARGS> -$Ticket => undef -$depth => 1 -$checked => {} -</%ARGS> +return unless $depends or $approvals; +</%init> diff --git a/rt/share/html/Ticket/Elements/ShowGnuPGStatus b/rt/share/html/Ticket/Elements/ShowGnuPGStatus deleted file mode 100644 index efaf663..0000000 --- a/rt/share/html/Ticket/Elements/ShowGnuPGStatus +++ /dev/null @@ -1,177 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<table class="crypt-runs"> -<tr><td align="right" class="labeltop" rowspan="<% scalar @messages %>">GnuPG:</td> -<td><% shift @messages %></td></tr> - -% foreach my $msg( @messages ) { -<tr><td><% $msg %></td></tr> -% } -</table> -<%ARGS> -$Attachment -$WarnUnsigned => undef -$Reverify => 1 -</%ARGS> -<%INIT> -my @runs; -my $needs_unsigned_warning = $WarnUnsigned; - -foreach ( $Attachment->SplitHeaders ) { - if ( s/^X-RT-GnuPG-Status:\s*//i ) { - require RT::Crypt::GnuPG; - push @runs, [ RT::Crypt::GnuPG::ParseStatus( $_ ) ]; - } - - $needs_unsigned_warning = 0 if /^X-RT-Incoming-Signature:/; - - # if this is not set, then the email is generated by RT, and so we don't - # need "email is unsigned" warnings - $needs_unsigned_warning = 0 if not /^Received:/; -} - -return unless @runs or $needs_unsigned_warning; - -my $reverify_cb = sub { - my $top = shift; - - my $txn = $top->TransactionObj; - unless ( $txn && $txn->id ) { - return (0, "Couldn't get transaction of attachment #". $top->id); - } - - my $attachments = $txn->Attachments->Clone; - $attachments->Limit( FIELD => 'ContentType', VALUE => 'application/x-rt-original-message' ); - my $original = $attachments->First; - unless ( $original ) { - return (0, "Couldn't find attachment with original email of transaction #". $txn->id); - } - - my $parser = RT::EmailParser->new(); - $parser->SmartParseMIMEEntityFromScalar( - Message => $original->Content, - Decode => 0, - Exact => 1, - ); - my $entity = $parser->Entity; - unless ( $entity ) { - return (0, "Couldn't parse content of attachment #". $original->id); - } - - use RT::Interface::Email::Auth::GnuPG; - my ($status, @res) = RT::Interface::Email::Auth::GnuPG::VerifyDecrypt( Entity => $entity ); - if ( $status && !@res ) { - # imposible in this situation - return (0, "Content of attachment #". $original->id ." is not signed and/or encrypted"); - } - elsif ( @res ) { - require RT::Crypt::GnuPG; - - $top->DelHeader('X-RT-GnuPG-Status'); - $top->AddHeader(map { ('X-RT-GnuPG-Status' => $_->{'status'} ) } @res); - $top->SetHeader('X-RT-Privacy' => 'PGP' ); - $top->DelHeader('X-RT-Incoming-Signature'); - - my @status = RT::Crypt::GnuPG::ParseStatus( $res[0]->{'status'} ); - for ( @status ) { - if ( $_->{'Operation'} eq 'Verify' && $_->{'Status'} eq 'DONE' ) { - $top->AddHeader( 'X-RT-Incoming-Signature' => $_->{'UserString'} ); - $needs_unsigned_warning = 0; - } - } - } - return (1, "Reverified original message"); -}; - -my @messages; -foreach my $run ( @runs ) { - foreach my $line ( @$run ) { - if ( $line->{'Operation'} eq 'KeyCheck' ) { - next unless $Reverify; - # if a public key was missing during verification then we want try again - next unless $line->{'KeyType'} eq 'public' && $line->{'Status'} eq 'MISSING'; - - # but only if we have key - my %key = RT::Crypt::GnuPG::GetPublicKeyInfo( $line->{'Key'} ); - if ( $key{'info'} ) { - my ($status, $msg) = $reverify_cb->($Attachment); - unless ($status) { - $RT::Logger->error($msg); - } else { - return $m->comp('SELF', %ARGS, Reverify => 0); - } - } - else { - push @messages, loc( "Public key '0x[_1]' is required to verify signature", $line->{'Key'} ); - } - } - elsif ( $line->{'Operation'} eq 'PassphraseCheck' ) { - next if $line->{'Status'} eq 'DONE'; - push @messages, loc( $line->{'Message'} ); - } - elsif ( $line->{'Operation'} eq 'Decrypt' ) { - push @messages, loc( $line->{'Message'} ); - } - elsif ( $line->{'Operation'} eq 'Verify' ) { - push @messages, loc( $line->{'Message'} ); - } - else { - next if $line->{'Status'} eq 'DONE'; - push @messages, loc( $line->{'Message'} ); - } - } -} - -push @messages, loc('Warning! This is NOT signed!') - if $needs_unsigned_warning; -return unless @messages; - -my %seen; -@messages = grep !$seen{$_}++, @messages; - -</%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowGroupMembers b/rt/share/html/Ticket/Elements/ShowGroupMembers index d42f528..dc5cc6b 100644 --- a/rt/share/html/Ticket/Elements/ShowGroupMembers +++ b/rt/share/html/Ticket/Elements/ShowGroupMembers @@ -46,22 +46,16 @@ %# %# END BPS TAGGED BLOCK }}} %# Released under the terms of version 2 of the GNU Public License - -% my $Users = $Group->UserMembersObj( Recursively => $Recursively ); -% while ( my $user = $Users->Next ) { -<& /Elements/ShowUser, User => $user, Ticket => $Ticket &> -<& /Elements/ShowUserEmailFrequency, User => $user, Ticket => $Ticket &> -% $m->callback( User => $user, Ticket => $Ticket, %ARGS, CallbackName => 'AboutThisUser' ); -<br /> -% } -% my $Groups = $Group->GroupMembersObj( Recursively => $Recursively ); -% $Groups->LimitToUserDefinedGroups; -% while (my $group = $Groups->Next) { -<&|/l&>Group</&>: <% $group->Name %><br /> -% } - +<%init> +my $post_user = sub { + my $user = shift; + $m->comp("/Elements/ShowUserEmailFrequency", User => $user, Ticket => $Ticket); + $m->callback( User => $user, Ticket => $Ticket, %ARGS, CallbackName => 'AboutThisUser', CallbackPage => '/Ticket/Elements/ShowGroupMembers' ); +}; +$m->comp("/Elements/ShowPrincipal", Object => $Group, Separator => "<br />", PostUser => $post_user, Link => $Link); +</%init> <%ARGS> $Group => undef -$Recursively => 0, $Ticket => undef +$Link => 1 </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowHistory b/rt/share/html/Ticket/Elements/ShowHistory deleted file mode 100755 index 835b66d..0000000 --- a/rt/share/html/Ticket/Elements/ShowHistory +++ /dev/null @@ -1,161 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<%doc> -# This is (ab)used in Admin/(Users|Groups)/History.html and should probably -# be generalized at some point. -</%doc> -<%perl> -if ($ShowDisplayModes or $ShowTitle) { - my $title = $ShowTitle - ? loc('History') - : ' '; - - my $titleright; - - if ($ShowDisplayModes) { - $titleright = ''; - - my $open_all = $m->interp->apply_escapes( loc("Show all quoted text"), 'j' ); - my $open_html = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' ); - my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'j' ); - $titleright .= '<a href="#" data-direction="open" ' - . qq{onclick="return toggle_all_folds(this, $open_all, $close_all);"} - . ">$open_html</a> — "; - - if ($ShowHeaders) { - $titleright .= qq{<a href="$URIFile?id=} . - $Ticket->id.qq{">} . - loc("Show brief headers") . - qq{</a>}; - } else { - $titleright .= qq{<a href="$URIFile?ShowHeaders=1;id=} . - $Ticket->id.qq{">} . - loc("Show full headers") . - qq{</a>}; - } - } -</%perl> -<div class="history"> -<& /Widgets/TitleBoxStart, title => $title, titleright_raw => $titleright &> -% } -<div id="ticket-history"> -<%perl> -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; - $m->callback( - %ARGS, - Transaction => $Transaction, - skip => \$skip, - CallbackName => 'SkipTransaction', - ); - next if $skip; - - $i++; - - my $IsLastTransaction = 0; - if ( RT->Config->Get( 'OldestTransactionsFirst', $session{'CurrentUser'} )){ - $IsLastTransaction = $Transactions->IsLast; - } else { - $IsLastTransaction = 1 if ( $i == 1 ); - } - - #Args is first because we're clobbering the "Attachments" parameter - $m->comp( 'ShowTransaction', - %ARGS, - - Ticket => $Ticket, - Transaction => $Transaction, - ShowHeaders => $ShowHeaders, - RowNum => $i, - Attachments => $trans_attachments->{$Transaction->id}, - AttachmentContent => $trans_content, - LastTransaction => $IsLastTransaction - ); - -# manually flush the content buffer after each txn, so the user sees -# some update -$m->flush_buffer(); -} - -</%perl> -</div> -% if ($ShowDisplayModes or $ShowTitle) { -<& /Widgets/TitleBoxEnd &> -</div> -% } -<%INIT> - -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); - -</%INIT> -<%ARGS> -$URIFile => RT->Config->Get('WebPath')."/Ticket/Display.html" -$Ticket => undef -$Tickets => undef -$Transactions => undef -$Attachments => undef -$AttachmentContent => undef -$ShowHeaders => undef -$ShowTitle => 1 -$ShowDisplayModes => 1 -$WarnUnsigned => undef -</%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowMessageHeaders b/rt/share/html/Ticket/Elements/ShowMessageHeaders deleted file mode 100755 index 225218d..0000000 --- a/rt/share/html/Ticket/Elements/ShowMessageHeaders +++ /dev/null @@ -1,96 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -% if ( @headers ) { -<table> -% foreach my $header (@headers) { - <tr> - <td align="right" class="message-header-key"><% $header->{'Tag'} %>:</td> - <td class="message-header-value"><% $header->{'Value'} | n %></td> - </tr> -% } -</table> -% } -<%INIT> -my @headers; -foreach my $field( RT->Config->Get('ShowBccHeader')? $Message->_SplitHeaders : $Message->SplitHeaders ) { - my ($tag, $value) = split /:/, $field, 2; - next unless $tag && $value; - push @headers, { Tag => $tag, Value => $value }; -} - -my %display_headers = map { lc($_) => 1 } @DisplayHeaders; - -$m->callback( - message => $Message, - headers => \@headers, - display_headers => \%display_headers, -); - -unless ( $display_headers{'_all'} ) { - @headers = grep $display_headers{ lc $_->{'Tag'} }, @headers; -} - -my $ticket = $Message->TransactionObj->TicketObj; -foreach my $f (@headers) { - $m->comp('/Elements/MakeClicky', content => \$f->{'Value'}, ticket => $ticket, %ARGS); -} - -$m->callback( - CallbackName => 'BeforeLocalization', - headers => \@headers, -); - -if ( $Localize ) { - $_->{'Tag'} = loc($_->{'Tag'}) foreach @headers; -} -</%INIT> -<%ARGS> -$Message => undef -$Localize => 1 -@DisplayHeaders => ('_all') -</%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowMessageStanza b/rt/share/html/Ticket/Elements/ShowMessageStanza deleted file mode 100755 index 99f80c5..0000000 --- a/rt/share/html/Ticket/Elements/ShowMessageStanza +++ /dev/null @@ -1,188 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<%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); -}; - -$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' : '' ) . '"' - . '>' ); - -if ( ref $Message ) { - my @stack; - my $para = ''; - my $i = 0; - -AGAIN: foreach ( ; $i < @$Message; $i++ ) { - my $stanza = $Message->[$i]; - if ( ref $stanza eq "HASH" ) { - # 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 = ''; - - $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 = ''; - } - - if (@stack) { - ( $Message, $i ) = @{ pop @stack }; - $Depth--; - $m->out('</div>'); - goto AGAIN; - } -} else { - $print_content->( \$Message ); -} - -$m->out('</div>'); -$m->out('</pre>') - if ( $ContentType eq 'text/plain' - && $plain_text_pre - && !$Depth - && !$plain_text_mono ); -</%INIT> -<%ARGS> -$Message => undef -$Transaction => undef -$ContentType => 'text/plain' -</%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowPeople b/rt/share/html/Ticket/Elements/ShowPeople index 188cc23..b5b5dab 100755 --- a/rt/share/html/Ticket/Elements/ShowPeople +++ b/rt/share/html/Ticket/Elements/ShowPeople @@ -66,6 +66,7 @@ <td class="labeltop"><&|/l&>AdminCc</&>:</td> <td class="value"><& ShowGroupMembers, Group => $Ticket->AdminCc, Ticket => $Ticket &></td> </tr> + <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket, Grouping => 'People', Table => 0 &> </table> <%INIT> </%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowRequestor b/rt/share/html/Ticket/Elements/ShowRequestor index cfa079f..266604c 100755 --- a/rt/share/html/Ticket/Elements/ShowRequestor +++ b/rt/share/html/Ticket/Elements/ShowRequestor @@ -45,33 +45,28 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} +% if ($ShowTickets) { <script type="text/javascript"> jQuery(function() { - jQuery("#requestor-accordion").accordion({ - active: <% $count == 1 ? 0 : 'false' %>, - collapsible: true, - autoHeight: false - }); - -% if ($ShowTickets) { jQuery(".more-about-requestor-tickets").tabs({ cache: true, collapsible: true, selected: <% $selected %> }); -% } }); </script> +% } <&| /Widgets/TitleBox, title_raw => loc("More about the requestors"), class => 'ticket-info-requestor' &> -<div id="requestor-accordion"> +<div id="requestor-accordion" class="user-accordion"> % while ( my $requestor = $people->Next ) { - <h3><a href="#"><& /Elements/ShowUser, User => $requestor &></a></h3> +<h3><a href="#"><& /Elements/ShowUser, User => $requestor, Link => 0 &></a> + <a class="user-summary" href="<%RT->Config->Get('WebPath')%>/User/Summary.html?id=<%$requestor->Id%>">User Summary</a></h3> <div class="details"> %# Additional information about this user. Empty by default. @@ -85,6 +80,8 @@ </div> % } +% $m->callback( requestor => $requestor, %ARGS, CallbackName => 'AfterComments' ); + % if ( $ShowTickets ) { <div class="more-about-requestor-tickets ui-tabs" id="more-about-requestor-tickets-<%$requestor->Id%>"> <ul> @@ -108,7 +105,7 @@ <div id="requestor-<%$requestor->Id%>-ticket-tab-default"> <& $TicketTemplate, Requestor => $requestor &> % } else { - <div id="requestor-<%$requestor->Id%>-ticket-tab-<% $index++ %>" class="ui-tabs-hide"> + <div id="requestor-<%$requestor->Id%>-ticket-tab-<% $index++ %>" class="hidden"> <span class="label"><&|/l&>Loading...</&></span> % } </div> @@ -131,15 +128,13 @@ </div> % } -% if ( $has_right_adminusers ) { - <a class="modify-user" href="<% RT->Config->Get('WebPath')."/Admin/Users/Modify.html?id=".$requestor->id %>"><&|/l&>Modify this user</&></a> -% } - %# end of individual requestor details <div> </div> % } %# end of requestors loop +% $m->callback( %ARGS, CallbackName => 'AfterRequestors' ); + </div> </&> <%INIT> @@ -167,17 +162,20 @@ my $status_link_text = {Active => loc('Active 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' ) { +$ShowTickets = 0 if $DefaultTicketsTab eq 'None'; + +my $TicketTemplate; +if ($ShowTickets) { for (0 .. (@$status_order - 1)) { $selected = $_ && last if $status_order->[$_] eq $DefaultTicketsTab; } -} -my $TicketTemplate = "ShowRequestorTickets$DefaultTicketsTab"; -$TicketTemplate = "ShowRequestorTicketsActive" - unless RT::Interface::Web->ComponentPathIsSafe($TicketTemplate) - and $m->comp_exists($TicketTemplate); + $TicketTemplate = "ShowRequestorTickets$DefaultTicketsTab"; + $TicketTemplate = "ShowRequestorTicketsActive" + unless RT::Interface::Web->ComponentPathIsSafe($TicketTemplate) + and $m->comp_exists($TicketTemplate); +} </%INIT> <%ARGS> $Ticket=>undef diff --git a/rt/share/html/Ticket/Elements/ShowRequestorExtraInfo b/rt/share/html/Ticket/Elements/ShowRequestorExtraInfo index 42c8f25..cd2dbc8 100644 --- a/rt/share/html/Ticket/Elements/ShowRequestorExtraInfo +++ b/rt/share/html/Ticket/Elements/ShowRequestorExtraInfo @@ -45,45 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<div class="more-about-requestor-extra"> -% for my $column (@formats) { -% my $title = $column->{title} || ''; -% my $attr = $column->{'attribute'} || $column->{'last_attribute'}; -% unless (defined $column->{title}) { -% $title = $fetch_columnmap->($attr,'title',[$attr]); -% } -% $title = $m->comp('/Elements/ScrubHTML', Content => $title); -<div class="more-about-requestor-extra-field <% $fetch_columnmap->($attr,'attribute',[$attr]) %>" > -<span class="label"><% loc($title) %></span> -% my @out; -% foreach my $subcol ( @{ $column->{output} } ) { -% my ($col) = ($subcol =~ /^__(.*?)__$/); -% unless ( $col ) { -% push @out, $subcol; -% next; -% } -% push @out, $fetch_columnmap->($col, 'value', [$Requestor]); -% } -% @out = grep { defined $_ and length $_ } @out; -<span class="value"><% join(' ',@out) %></span> -</div> -% } -</div> -<%INIT> -my $format = RT->Config->Get('MoreAboutRequestorExtraInfo'); -my @formats = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $format); - -my $fetch_columnmap = sub { - my ($name, $attr, $arguments) = @_; - my $tmp = $m->comp( '/Elements/ColumnMap', - Class => $Class, - Name => $name, - Attr => $attr, - ); - return ProcessColumnMapValue( $tmp, Arguments => $arguments, Escape => 0 ); -}; -</%INIT> +<& /User/Elements/UserInfo, User => $Requestor, FormatConfig => 'MoreAboutRequestorExtraInfo', ClassPrefix => 'more-about-requestor' &> <%ARGS> $Requestor => undef -$Class => 'RT__User'; </%ARGS> diff --git a/rt/share/html/Ticket/Elements/ShowRequestorTickets b/rt/share/html/Ticket/Elements/ShowRequestorTickets index 1213d3d..55e7819 100644 --- a/rt/share/html/Ticket/Elements/ShowRequestorTickets +++ b/rt/share/html/Ticket/Elements/ShowRequestorTickets @@ -45,31 +45,21 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<span class="label"> - <a href="<% $url %>"><&|/l, $Rows, $Description &>This user's [_1] highest priority [_2] tickets</&>:</a> -</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> +<& /User/Elements/TicketList, + User => $Requestor, + conditions => $conditions, + Rows => $Rows, + Title => $Title, + WatcherTypes => ['Requestor'], + Format => => RT->Config->Get('MoreAboutRequestorTicketListFormat'), + &> <%INIT> -my $sql = "Requestor.id = ". $Requestor->id; -if (@$conditions) { - $sql .= " AND (".join( " OR ", map $_->{cond}, @$conditions).")"; -} -my $tickets = RT::Tickets->new( $session{'CurrentUser'} ); -$tickets->FromSQL( $sql ); -$tickets->RowsPerPage( $Rows ); -$tickets->OrderBy( FIELD => 'Priority', ORDER => 'DESC' ); +my $Title = loc("This user's [_1] highest priority [_2] tickets", $Rows, $Description ); -my $url = RT->Config->Get('WebPath') . '/Search/Results.html?'; - $url .= $m->comp('/Elements/QueryString', - Query => $sql, - OrderBy => 'Priority', - Order => 'DESC' ); +$m->callback( CallbackName => 'ModifyTitle', + %ARGS, + Title => \$Title +); </%INIT> <%ARGS> $Requestor => undef diff --git a/rt/share/html/Ticket/Elements/ShowSimplifiedRecipients b/rt/share/html/Ticket/Elements/ShowSimplifiedRecipients index 73c1fd9..2f07456 100644 --- a/rt/share/html/Ticket/Elements/ShowSimplifiedRecipients +++ b/rt/share/html/Ticket/Elements/ShowSimplifiedRecipients @@ -64,14 +64,6 @@ if ($Object->Scrips) { } } } -if ($Object->Rules) { - for my $rule (grep {$_->{hints} and $_->{hints}{class} eq "SendEmail"} @{$Object->Rules}) { - for my $type (qw(To Cc Bcc)) { - $headers{$type}{$_} ||= @{[Email::Address->parse($_)]}[0] # Hate list context - for @{$rule->{hints}{recipients}{$type}}; - } - } -} my %recips; my %squelched = ProcessTransactionSquelching( \%ARGS ); </%init> @@ -95,8 +87,9 @@ my %squelched = ProcessTransactionSquelching( \%ARGS ); % } % $m->callback( CallbackName => 'AfterRecipients', TicketObj => $TicketObj ); </table> -<i>(Uncheck boxes to disable notifications to the listed -recipients. Does <b>not</b> change who will receive future -updates.)</i> +<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> </&> % $m->notes("DryRun-Recipients-".$TicketObj->Id, \%recips); diff --git a/rt/share/html/Ticket/Elements/ShowSummary b/rt/share/html/Ticket/Elements/ShowSummary index 25782e6..9c8c8b4 100755 --- a/rt/share/html/Ticket/Elements/ShowSummary +++ b/rt/share/html/Ticket/Elements/ShowSummary @@ -53,11 +53,11 @@ (($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 &></&> - <&| /Widgets/TitleBox, title => loc('Custom Fields'), - (($can_modify || $can_modify_cf) ? (title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id) : ()), - class => 'ticket-info-cfs', - hide_empty => 1, - &><& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &></&> + + <& /Elements/ShowCustomFieldCustomGroupings, + Object => $Ticket, + title_href => ($can_modify || $can_modify_cf) ? RT->Config->Get('WebPath')."/Ticket/Modify.html" : "", + &> <&| /Widgets/TitleBox, title => loc('Customers'), #$can_modify_customers? @@ -70,6 +70,7 @@ class => 'ticket-info-people', &><& /Ticket/Elements/ShowPeople, Ticket => $Ticket &></&> <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &> +% $m->callback( %ARGS, CallbackName => 'AfterAttachments' ); <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &> % $m->callback( %ARGS, CallbackName => 'LeftColumn' ); </td> @@ -82,9 +83,7 @@ &> <table><tr><td> <form action="<%RT->Config->Get('WebPath')%>/Ticket/Display.html" name="UpdateReminders" id="UpdateReminders" method="post"> -% if ( $m->comp("/Ticket/Elements/Reminders", Ticket => $Ticket, ShowCompleted => 0) ) { - <div align="right"><input type="submit" class="button" value="<&|/l&>Save</&>" /></div> -% } + <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 0 &> </form> </td></tr></table> </&> @@ -100,7 +99,7 @@ ($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, Object => $Ticket &></&> % $m->callback( %ARGS, CallbackName => 'RightColumn' ); </td> </tr> @@ -112,9 +111,7 @@ $Attachments => undef <%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'); +my $can_modify_owner = $Ticket->CurrentUserCanSetOwner(); my $can_modify_people = $Ticket->CurrentUserHasRight('Watch') || $Ticket->CurrentUserHasRight('WatchAsAdminCc'); </%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowTime b/rt/share/html/Ticket/Elements/ShowTime index 2653146..2645353 100644 --- a/rt/share/html/Ticket/Elements/ShowTime +++ b/rt/share/html/Ticket/Elements/ShowTime @@ -46,9 +46,9 @@ %# %# END BPS TAGGED BLOCK }}} % if ($minutes < 60) { -<&|/l, $minutes &>[_1] min</&> +<&|/l, $minutes &>[quant,_1,minute,minutes]</&> % } else { -<&|/l, sprintf("%.1f",$minutes / 60) &>[quant,_1,hour]</&> (<&|/l, $minutes &>[_1] min</&>) +<&|/l, sprintf("%.1f",$minutes / 60), $minutes &>[quant,_1,hour,hours] ([quant,_2,minute,minutes])</&> % } <%init> $minutes ||= 0; diff --git a/rt/share/html/Ticket/Elements/ShowTransaction b/rt/share/html/Ticket/Elements/ShowTransaction deleted file mode 100755 index bf3c527..0000000 --- a/rt/share/html/Ticket/Elements/ShowTransaction +++ /dev/null @@ -1,240 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<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>\ - <% $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 %>\ -% $m->callback( Transaction => $Transaction, %ARGS, CallbackName => 'AfterDescription' ); -</span> -% $m->callback( TimeTaken => \$TimeTaken, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyTimeTaken' ); - <span class="time-taken"><% $TimeTaken %></span>\ - <span class="actions<% $titlebar_commands ? '': ' hidden'%>"><% $titlebar_commands |n %></span> - </div> - <div class="content"> -% 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 -$ShowHeaders => 0 -$Collapsed => undef -$ShowTitleBarCommands => 1 -$RowNum => 1 -$DisplayPath => RT->Config->Get('WebPath')."/Ticket/Display.html?id=".$Ticket->id -$AttachPath => RT->Config->Get('WebPath')."/Ticket/Attachment" -$UpdatePath => RT->Config->Get('WebPath')."/Ticket/Update.html" -$ForwardPath => RT->Config->Get('WebPath')."/Ticket/Forward.html" -$EncryptionPath => RT->Config->Get('WebPath')."/Ticket/GnuPG.html" -$EmailRecordPath => RT->Config->Get('WebPath')."/Ticket/ShowEmailRecord.html" -$Attachments => undef -$AttachmentContent => undef -$ShowBody => 1 -$LastTransaction => 0 -$WarnUnsigned => undef -</%ARGS> -<%ONCE> - -my %class = ( - Correspond => 'message', - Comment => 'message', - - AddWatcher => 'people', - DelWatcher => 'people', - Take => 'people', - Untake => 'people', - Force => 'people', - Steal => 'people', - Give => 'people', - - AddLink => 'links', - DeleteLink => 'links', -); - -</%ONCE> -<%INIT> - -my $transdate = $Transaction->CreatedAsString(); -$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' ) { - $type_class = 'people'; - } - elsif ( $type =~ /^(Status|Set|Told)$/ ) { - if ( $field =~ /^(Told|Starts|Started|Due)$/ ) { - $type_class = 'dates'; - } - else { - $type_class = 'basics'; - } - } - else { - $type_class = 'other'; - } -} - -$m->callback( - CallbackName => 'MassageTypeClass', - Transaction => $Transaction, - TypeClassRef => \$type_class, - ARGSRef => \%ARGS, -); - -my $TicketString = ''; -if ( $Ticket->Id != $Transaction->Ticket ) { - $TicketString = loc("Ticket #[_1]:", $Transaction->Ticket) .' '; -} - -my $TimeTaken = ''; -$TimeTaken = $Transaction->TimeTaken . " min" - if $Transaction->TimeTaken; - -unless ($Attachments) { - my $attachments = $Transaction->Attachments; - $attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId) ); - $ARGS{'Attachments'} = $Attachments = $attachments->ItemsArrayRef(); -} -my $titlebar_commands = ''; - -$m->callback( - CallbackName => 'MassageAttachments', - Transaction => $Transaction, - AttachmentsRef => \$Attachments, - ARGSRef => \%ARGS, -); - -if ( $type =~ /EmailRecord$/ ) { - - $titlebar_commands .= - "[<a target=\"_blank\" href=\"$EmailRecordPath?id=" - . $Transaction->Ticket - . "&Transaction=" - . $Transaction->Id - . "&Attachment=" - . ( $Attachments->[0] && $Attachments->[0]->id ) - . '">' . loc('Show') . "</a>] "; - $ShowBody = 0; -} - - -# If the transaction has anything attached to it at all -else { - - if ( $Attachments->[0] && $ShowTitleBarCommands ) { - my $ticket = $Transaction->TicketObj; - my $can_modify = $ticket->CurrentUserHasRight('ModifyTicket'); - if ( $can_modify || $ticket->CurrentUserHasRight('ReplyToTicket') ) { - $titlebar_commands .= - "[<a href=\"" . $UpdatePath - . "?id=" . $Transaction->Ticket - . "&QuoteTransaction=" . $Transaction->Id - . "&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\" " - . "class=\"comment-link\"" - . ">" - . loc('Comment') - . "</a>]"; - } - if ( $ticket->CurrentUserHasRight('ForwardMessage') ) { - $titlebar_commands .= - "[<a href=\"" . $ForwardPath - . "?id=" . $Transaction->Ticket - . "&QuoteTransaction=" . $Transaction->Id ."\" " - . "class=\"forward-link\"" - . ">" - . loc('Forward') - . "</a>]"; - } - if ( $can_modify - && RT->Config->Get('GnuPG')->{'Enable'} - && RT->Config->Get('GnuPG')->{'AllowEncryptDataInDB'} - && $ticket->CurrentUserHasRight('ForwardMessage') - ) { - $titlebar_commands .= - "[<a href=\"" . $EncryptionPath - . "?id=" . $Transaction->Id ."\" " - . "class=\"gpg-link\"" - . ">" - . loc('Encrypt/Decrypt') - . "</a>]"; - } - } -} -</%INIT> diff --git a/rt/share/html/Ticket/Elements/ShowTransactionAttachments b/rt/share/html/Ticket/Elements/ShowTransactionAttachments deleted file mode 100644 index 477a81a..0000000 --- a/rt/share/html/Ticket/Elements/ShowTransactionAttachments +++ /dev/null @@ -1,301 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -<%PERL> -# Find all the attachments which have parent $Parent -# For each of these attachments -foreach my $message ( grep $_->__Value('Parent') == $Parent, @$Attachments ) { - - if (RT->Config->Get('GnuPG')->{'Enable'}) { - $m->comp( 'ShowGnuPGStatus', Attachment => $message, WarnUnsigned => $WarnUnsigned ); - } - - $m->comp( 'ShowMessageHeaders', - Message => $message, - DisplayHeaders => \@DisplayHeaders, - ); - - 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 %>/<% $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"> -% } else { -<div class="messagebody"> -% } -<%PERL> - -$render_attachment->( $message ); - -$m->comp( - $m->current_comp, - %ARGS, - Parent => $message->id, - ParentObj => $message -); - -</%PERL> -</div> -% } -<%ARGS> -$Ticket => undef -$Transaction => undef -$ShowHeaders => 0 -$Collapsed => undef -$DownloadableHeaders => 1 -$ShowTitleBarCommands => 1 -$RowNum => 1 -$AttachPath => RT->Config->Get('WebPath')."/Ticket/Attachment" -$UpdatePath => RT->Config->Get('WebPath')."/Ticket/Update.html" -$EmailRecordPath => RT->Config->Get('WebPath')."/Ticket/ShowEmailRecord.html" -$Attachments => undef -$AttachmentContent => {} -$ShowBody => 1 -$Parent => 0 -$ParentObj => undef -$WarnUnsigned => 0 -</%ARGS> -<%INIT> -my @DisplayHeaders=qw(_all); -if ( $Transaction->Type =~ /EmailRecord$/ ) { - @DisplayHeaders = qw(To Cc Bcc); -} - -# If the transaction has anything attached to it at all -elsif (!$ShowHeaders) { - @DisplayHeaders = qw(To From RT-Send-Cc Cc Bcc Date Subject); - 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 - if ( $size > 1024*1024 ) { - $size = loc( "[_1]m", int( $size / 1024 / 102.4 ) / 10 ); - } - elsif ( $size > 1024 ) { - $size = loc( "[_1]k", int( $size / 102.4 ) / 10 ); - } - else { - $size = loc( "[_1]b", $size ); - } - return $size; -}; - -my $render_attachment = sub { - my $message = shift; - my $name = defined $message->Filename && length $message->Filename ? $message->Filename : ''; - - my $content_type = lc $message->ContentType; - - # if it has a content-disposition: attachment, don't show inline - my $disposition = $message->GetHeader('Content-Disposition'); - - if ( $disposition && $disposition =~ /^\s*attachment/i ) { - $disposition = 'attachment'; - } else { - $disposition = 'inline'; - } - - # If it's text - if ( $content_type =~ m{^(text|message)/} ) { - my $max_size = RT->Config->Get( 'MaxInlineBody', $session{'CurrentUser'} ); - if ( $disposition ne 'inline' ) { - $m->out('<p>'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'</p>'); - return; - } - 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 ( $max_size && $message->ContentLength > $max_size ) { - $m->out('<p>'. loc( 'Message body is not shown because it is too large.' ) .'</p>'); - return; - } - - if ( - - # it's a toplevel object - !$ParentObj - - # or its parent isn't a multipart alternative - || ( $ParentObj->ContentType !~ m{^multipart/(?:alternative|related)$}i ) - - # or it's of our prefered alterative type - || ( - ( - RT->Config->Get('PreferRichText') - && ( $content_type =~ m{^text/(?:html|enriched)$} ) - ) - || ( !RT->Config->Get('PreferRichText') - && ( $content_type !~ m{^text/(?:html|enriched)$} ) - ) - ) - ) { - - my $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; - } - - $RT::Logger->debug( - "Rendering attachment #". $message->id - ." of '$content_type' type" - ); - - # if it's a text/html clean the body and show it - if ( $content_type eq 'text/html' ) { - $content = $m->comp( '/Elements/ScrubHTML', Content => $content ); - - $m->comp( - '/Elements/MakeClicky', - content => \$content, - html => 1, - ticket => $Ticket, - ); - - unless (length $name) { - eval { - require HTML::Quoted; - $content = HTML::Quoted->extract($content) - }; - if ($@) { - RT->Logger->error( - "HTML::Quoted couldn't process attachment #@{[$message->id]}: $@." - . " This is a bug, please report it to rt-bugs\@bestpractical.com."); - } - } - - $m->comp( - 'ShowMessageStanza', - Message => $content, - Transaction => $Transaction, - ContentType => 'text/html', - ); - } - - elsif ( $content_type eq 'text/enriched' ) { - $content = $m->comp( '/Elements/ScrubHTML', Content => $content ); - $m->out( $content ); - } - - # It's a text type we don't have special handling for - else { - unless ( length $name ) { - eval { - require Text::Quoted; - # XXX: Deprecate ->can check in 4.2 and simply bump version requirement. - Text::Quoted::set_quote_characters(undef) # only use > - if Text::Quoted->can("set_quote_characters"); - $content = Text::Quoted::extract($content); - }; - if ($@) { - RT->Logger->error( - "Text::Quoted couldn't process attachment #@{[$message->id]}: $@." - . " This is a bug, please report it to rt-bugs\@bestpractical.com."); - } - } - - $m->comp( - 'ShowMessageStanza', - Message => $content, - Transaction => $Transaction, - ContentType => 'text/plain', - ); - } - } - } - - # if it's an image, show it as an image - elsif ( RT->Config->Get('ShowTransactionImages') and $content_type =~ m{^image/} ) { - if ( $disposition ne 'inline' ) { - $m->out('<p>'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'</p>'); - return; - } - - my $filename = length $name ? $name : loc('(untitled)'); - my $efilename = $m->interp->apply_escapes( $filename, 'h' ); - $m->out('<img' - . ' alt="' - . $efilename - . '"' - . ' title="' - . $efilename - . '"' - . ' src="' - . $AttachPath . '/' - . $Transaction->Id . '/' - . $message->Id - . '/" />' ); - } - elsif ( $message->ContentLength && $message->ContentLength > 0 ) { - $m->out( '<p>' . - loc( 'Message body not shown because it is not plain text.' ) . - '</p>' - ); - } -}; - -</%INIT> diff --git a/rt/share/html/Ticket/Elements/UpdateCc b/rt/share/html/Ticket/Elements/UpdateCc index eaa78c5..843dd3b 100644 --- a/rt/share/html/Ticket/Elements/UpdateCc +++ b/rt/share/html/Ticket/Elements/UpdateCc @@ -47,7 +47,7 @@ %# END BPS TAGGED BLOCK }}} % $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} &> +<tr><td class="label"><&|/l&>One-time Cc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateCc', Size => undef, Default => $ARGS{UpdateCc}, AutocompleteMultiple => 1 &> <input type="hidden" id="UpdateIgnoreAddressCheckboxes" name="UpdateIgnoreAddressCheckboxes" value="0"> <br /> @@ -62,10 +62,11 @@ type="checkbox" % my $clean_addr = $txn_addresses{$addr}->format; onClick="checkboxToInput('UpdateCc', <% "UpdateCc-$addr" |n,j%>, <%$clean_addr|n,j%> );" - <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> > <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> + <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> > + <label for="UpdateCc-<%$addr%>"><& /Elements/ShowUser, Address => $txn_addresses{$addr}&></label> %} </td></tr> -<tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => undef, Default => $ARGS{UpdateBcc} &><br /> +<tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => undef, Default => $ARGS{UpdateBcc}, AutocompleteMultiple => 1 &><br /> %if (scalar @one_time_Ccs) { <i class="label">(<&|/l&>check to add</&>)</i> %} @@ -77,8 +78,8 @@ type="checkbox" % my $clean_addr = $txn_addresses{$addr}->format; onClick="checkboxToInput('UpdateBcc', <% "UpdateBcc-$addr" |n,j%>, <%$clean_addr|n,j%> );" - <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%>> -<& /Elements/ShowUser, Address => $txn_addresses{$addr}&> + <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%> > + <label for="UpdateBcc-<%$addr%>"><& /Elements/ShowUser, Address => $txn_addresses{$addr}&></label> %} </td></tr> <%args> diff --git a/rt/share/html/Ticket/Forward.html b/rt/share/html/Ticket/Forward.html index e457aeb..2970298 100644 --- a/rt/share/html/Ticket/Forward.html +++ b/rt/share/html/Ticket/Forward.html @@ -61,19 +61,32 @@ <td><% $from %></td></tr> <tr><td align="right"><&|/l&>Subject</&>:</td> -<td><% $subject %></td></tr> +<td><input name="Subject" size="60" value="<% $ARGS{'Subject'} || $subject %>" /></td></tr> <tr><td align="right"><&|/l&>To</&>:</td> -<td><input name="To" size="60" value="<% $ARGS{'To'} || '' %>" /></td></tr> +<td><& /Elements/EmailInput, Name => "To", AutocompleteMultiple => 1, Default => $ARGS{'To'} &></td></tr> <tr><td align="right"><&|/l&>Cc</&>:</td> -<td><input name="Cc" size="60" value="<% $ARGS{'Cc'} || '' %>" /></td></tr> +<td><& /Elements/EmailInput, Name => "Cc", AutocompleteMultiple => 1, Default => $ARGS{'Cc'} &></td></tr> <tr><td align="right"><&|/l&>Bcc</&>:</td> -<td><input name="Bcc" size="60" value="<% $ARGS{'Bcc'} || '' %>" /></td></tr> +<td><& /Elements/EmailInput, Name => "Bcc", AutocompleteMultiple => 1, Default => $ARGS{'Bcc'} &></td></tr> + +<tr> +<td><&|/l&>Content</&>:</td> +<td> +% if (exists $ARGS{Content}) { +<& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => 0 &> +% } else { +<& /Elements/MessageBox &> +%} +</td> +</tr> </table> +<& /Ticket/Elements/ShowAttachments, Ticket => $TicketObj, Attachments => $attachments &> + <& /Elements/Submit, Label => loc('Forward Message and Return'), Name => 'ForwardAndReturn' &> <& /Elements/Submit, Label => loc('Forward Message'), Name => 'Forward' &> </form> @@ -94,10 +107,7 @@ if ( $QuoteTransaction ) { my @results; if ( $Forward || $ForwardAndReturn ) { - require RT::Interface::Email; - my ($status, $msg) = $txn - ? RT::Interface::Email::ForwardTransaction( $txn, %ARGS ) - : RT::Interface::Email::ForwardTicket( $TicketObj, %ARGS ); + my ( $status, $msg ) = $TicketObj->Forward( Transaction => $txn, %ARGS ); push @results, $msg; if ( $ForwardAndReturn ) { @@ -115,9 +125,12 @@ my $Title = $txn 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'); +my $subject = "Fwd: ".($txn || $TicketObj)->Subject; + +my $attachments = RT::Interface::Email::GetForwardAttachments( + Ticket => $TicketObj, + $txn ? ( Transaction => $txn ) : (), +); </%INIT> diff --git a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties index 2079202..45dbd7d 100644 --- a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties +++ b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties @@ -72,7 +72,8 @@ % foreach my $type ( @link_types ) { % my $checked = ''; % $checked = 'checked="checked"' if grep $type eq $_, @ShowLinks; -<input type="checkbox" name="ShowLinks" value="<% $type %>" <% $checked |n %> /><% loc($type) %> +<input type="checkbox" id="ShowLinks" name="ShowLinks" value="<% $type %>" <% $checked |n %> /> +<label for="ShowLinks"><% loc($type) %></label> % } <br /> @@ -98,8 +99,8 @@ while ( my ($group, $list) = (splice @tmp, 0, 2) ) { % if ( RT::Link->can('Description' ) ) { % my $checked = ''; % $checked = 'checked="checked"' if $ShowLinkDescriptions; -<% loc('Show link descriptions') %>: -<input type="checkbox" name="ShowLinkDescriptions" value="1" <% $checked |n %> /> +<label for="ShowLinkDescriptions"><% loc('Show link descriptions') %>:</label> +<input type="checkbox" id="ShowLinkDescriptions" name="ShowLinkDescriptions" value="1" <% $checked |n %> /> <br /> % } @@ -158,7 +159,8 @@ $class = 'class="hidden"' if $Level != 1 && !@Default; % foreach my $prop ( @$list ) { % my $checked = ''; % $checked = 'checked="checked"' if grep $_ eq $prop, @Default; -<input type="checkbox" class="checkbox" name="Level-<% $Level %>-Properties" value="<% $prop %>" <% $checked |n %> /><% loc($prop) %> +<input type="checkbox" class="checkbox" id="Level-<% $Level %>-Properties" name="Level-<% $Level %>-Properties" value="<% $prop %>" <% $checked |n %> /> +<label for="Level-<% $Level %>-Properties"><% loc($prop) %></label> % } </td></tr> % } diff --git a/rt/share/html/Ticket/History.html b/rt/share/html/Ticket/History.html index 3fa05fe..0837c99 100755 --- a/rt/share/html/Ticket/History.html +++ b/rt/share/html/Ticket/History.html @@ -53,12 +53,12 @@ <br /> -<& /Ticket/Elements/ShowHistory , - Ticket => $Ticket, +<& /Elements/ShowHistory, + Object => $Ticket, ShowHeaders => $ARGS{'ShowHeaders'}, - URIFile => 'History.html', Attachments => $attachments, - AttachmentContent => $attachment_content + AttachmentContent => $attachment_content, + DisplayPath => 'History.html', &> % $m->callback( %ARGS, CallbackName => 'AfterShowHistory', Ticket => $Ticket ); @@ -77,9 +77,8 @@ unless ($Ticket->CurrentUserHasRight('ShowTicket')) { Abort("No permission to view ticket"); } -my $attachments = $m->comp('Elements/FindAttachments', Ticket => $Ticket); -my $attachment_content = $m->comp('Elements/LoadTextAttachments', Ticket => -$Ticket); +my $attachments = $Ticket->Attachments; +my $attachment_content = $Ticket->TextAttachments; </%INIT> diff --git a/rt/share/html/Ticket/Modify.html b/rt/share/html/Ticket/Modify.html index af417e9..40adbda 100755 --- a/rt/share/html/Ticket/Modify.html +++ b/rt/share/html/Ticket/Modify.html @@ -56,36 +56,61 @@ <input type="hidden" class="hidden" name="id" value="<% $TicketObj->Id %>" /> <&| /Widgets/TitleBox, title => loc('Modify ticket #[_1]',$TicketObj->Id), class=>'ticket-info-basics' &> -<& Elements/EditBasics, TicketObj => $TicketObj &> -<& Elements/EditCustomFields, TicketObj => $TicketObj, DefaultsFromTopArguments => 0 &> +<table> +<& Elements/EditBasics, TicketObj => $TicketObj, defaults => \%ARGS, InTable => 1 &> +<& Elements/EditCustomFields, Object => $TicketObj, Grouping => 'Basics', InTable => 1, DefaultsFromTopArguments => 0 &> +</table> </&> % $m->callback( CallbackName => 'AfterBasics', Ticket => $TicketObj ); +<& /Elements/EditCustomFieldCustomGroupings, Object => $TicketObj &> + <& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#993333" &> </form> + +% $m->callback(CallbackName => 'AfterForm', ARGSRef => \%ARGS, Ticket => $TicketObj); <%INIT> my $TicketObj = LoadTicket($id); my $CustomFields = $TicketObj->CustomFields; -# call this to show up hints of valid cf values. -$m->comp( - '/Elements/ValidateCustomFields', - CustomFields => $CustomFields, - ARGSRef => {}, -); +my @results; +my $skip_update = 0; # Now let callbacks have a chance at editing %ARGS -$m->callback( TicketObj => $TicketObj, CustomFields => $CustomFields, ARGSRef => \%ARGS ); +$m->callback( TicketObj => $TicketObj, CustomFields => $CustomFields, ARGSRef => \%ARGS, skip_update => \$skip_update, results => \@results ) -my @results; -push @results, ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS); -push @results, ProcessObjectCustomFieldUpdates(Object => $TicketObj, ARGSRef => \%ARGS); push @results, ProcessTicketStatus(TicketObj => $TicketObj, ARGSRef => \%ARGS); # for WillResolve push @results, ProcessTicketDates( TicketObj => $TicketObj, ARGSRef => \%ARGS); -$TicketObj->ApplyTransactionBatch; +{ + my ($status, @msg) = $m->comp( + '/Elements/ValidateCustomFields', + Object => $TicketObj, + CustomFields => $CustomFields, + ARGSRef => \%ARGS, + ); + unless ($status) { + push @results, @msg; + $skip_update = 1; + } +} + +unless ($skip_update) { + push @results, ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS); + push @results, ProcessObjectCustomFieldUpdates(Object => $TicketObj, ARGSRef => \%ARGS); + $m->callback( CallbackName => 'ProcessUpdates', TicketObj => $TicketObj, + ARGSRef => \%ARGS, Results => \@results ); + + $TicketObj->ApplyTransactionBatch; + + MaybeRedirectForResults( + Actions => \@results, + Path => "/Ticket/Modify.html", + Arguments => { id => $TicketObj->id }, + ); +} unless ($TicketObj->CurrentUserHasRight('ShowTicket')) { if (@results) { diff --git a/rt/share/html/Ticket/ModifyAll.html b/rt/share/html/Ticket/ModifyAll.html index 20471ac..f0b70b5 100755 --- a/rt/share/html/Ticket/ModifyAll.html +++ b/rt/share/html/Ticket/ModifyAll.html @@ -55,14 +55,16 @@ % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); <input type="submit" name="SubmitTicket" value="Save Changes" style="display:none"> <input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" /> +<input type="hidden" class="hidden" name="Token" value="<% $ARGS{'Token'} %>" /> <&| /Widgets/TitleBox, title => loc('Modify ticket # [_1]', $Ticket->Id), class=>'ticket-info-basics' &> -<& Elements/EditBasics, TicketObj => $Ticket &> -<& Elements/EditCustomFields, TicketObj => $Ticket &> +<& Elements/EditBasics, TicketObj => $Ticket, defaults => \%ARGS &> +<& /Elements/EditCustomFields, Object => $Ticket, Grouping => 'Basics' &> </&> % $m->callback(CallbackName => 'AfterBasics', Ticket => $Ticket); -<br /> + +<& /Elements/EditCustomFieldCustomGroupings, Object => $Ticket &> <&| /Widgets/TitleBox, title => loc('Dates'), class=>'ticket-info-dates'&> <& Elements/EditDates, TicketObj => $Ticket &> @@ -78,7 +80,13 @@ <br /> <&| /Widgets/TitleBox, title => loc('Links'), class=>'ticket-info-links' &> -<& /Elements/EditLinks, Object => $Ticket, Merge => 1 &> +<& /Elements/EditLinks, Object => $Ticket &> +</&> + +<br /> + +<&| /Widgets/TitleBox, title => loc('Merge'), class=>'ticket-info-merge' &> +<& Elements/EditMerge, Ticket => $Ticket, %ARGS &> </&> <br /> @@ -88,7 +96,7 @@ <tr> <td class="label"><&|/l&>Update Type</&>:</td> <td class="entry"> - <select name="UpdateType"> + <select name="UpdateType" id="UpdateType"> % if ($CanComment) { <option value="private" ><&|/l&>Comments (Not sent to requestors)</&></option> % } @@ -112,8 +120,9 @@ <tr> <td class="labeltop"><&|/l&>Content</&>:</td> - <td class="entry"> -% if ( defined $ARGS{UpdateContent} && length $ARGS{UpdateContent} ) { + <td class="entry messagebox-container action-<% $ARGS{UpdateType} || ($CanComment ? 'private' : 'response') %>"> +% $m->callback( %ARGS, CallbackName => 'BeforeMessageBox' ); +% if (defined $ARGS{UpdateContent} && length($ARGS{UpdateContent})) { <& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0 &> % } else { <& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &> @@ -129,6 +138,8 @@ Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &> </form> +% $m->callback(CallbackName => 'AfterForm', ARGSRef => \%ARGS, Ticket => $Ticket); + <%INIT> @@ -136,13 +147,6 @@ my $Ticket = LoadTicket($id); my $CustomFields = $Ticket->CustomFields; -# call this to show up hints of valid cf values. -$m->comp( - '/Elements/ValidateCustomFields', - CustomFields => $CustomFields, - ARGSRef => {}, -); - my $CanRespond = 0; my $CanComment = 0; @@ -155,47 +159,56 @@ $CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or ProcessAttachments(ARGSRef => \%ARGS); -$m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS ); my @results; - -unless ($OnlySearchForPeople or $OnlySearchForGroup or $ARGS{'AddMoreAttach'} ) { - # There might be two owners. - if ( ref ($ARGS{'Owner'} )) { - my @owners =@{$ARGS{'Owner'}}; - delete $ARGS{'Owner'}; - foreach my $owner(@owners){ - 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); - } - } - +my $skip_update = 0; +$m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS, skip_update => \$skip_update, results => \@results ); + +{ + my ($status, @msg) = $m->comp( + '/Elements/ValidateCustomFields', + Object => $Ticket, + CustomFields => $CustomFields, + ARGSRef => \%ARGS, + ); + unless ($status) { + push @results, @msg; + $skip_update = 1; } +} + +# There might be two owners. +if ( ref ($ARGS{'Owner'} )) { + my @owners =@{$ARGS{'Owner'}}; + delete $ARGS{'Owner'}; + foreach my $owner(@owners){ + 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); + } + } +} +unless ($skip_update or $OnlySearchForPeople or $OnlySearchForGroup or $ARGS{'AddMoreAttach'} ) { push @results, ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS); push @results, ProcessObjectCustomFieldUpdates( Object => $Ticket, ARGSRef => \%ARGS); push @results, ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS); - - # Add session attachments if any to be processed by ProcessUpdateMessage - $ARGS{'UpdateAttachments'} = $session{'Attachments'} if ( $session{'Attachments'} ); push @results, ProcessUpdateMessage( TicketObj => $Ticket, ARGSRef=>\%ARGS ); - # Cleanup WebUI - delete $session{'Attachments'}; - push @results, ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS ); push @results, ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS); } push @results, ProcessTicketStatus( TicketObj => $Ticket, ARGSRef => \%ARGS ); -$Ticket->ApplyTransactionBatch; + $Ticket->ApplyTransactionBatch; -MaybeRedirectForResults( - Actions => \@results, - Path => "/Ticket/ModifyAll.html", - Arguments => { id => $Ticket->id }, -); + MaybeRedirectForResults( + Actions => \@results, + Path => "/Ticket/ModifyAll.html", + Arguments => { id => $Ticket->id }, + ); + +} # If they've gone and moved the ticket to somewhere they can't see, etc... unless ($Ticket->CurrentUserHasRight('ShowTicket')) { diff --git a/rt/share/html/Ticket/ModifyDates.html b/rt/share/html/Ticket/ModifyDates.html index faf7ffa..ebd33bd 100755 --- a/rt/share/html/Ticket/ModifyDates.html +++ b/rt/share/html/Ticket/ModifyDates.html @@ -45,21 +45,22 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Elements/Header, Title => loc('Modify dates for #[_1]', $TicketObj->Id) &> +<& /Elements/Header, Title => loc('Modify dates for ticket #[_1]', $TicketObj->Id) &> <& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj); <& /Elements/ListActions, actions => \@results &> -<form method="post" action="ModifyDates.html"> +<form method="post" action="ModifyDates.html" name="TicketDates"> % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); <input type="hidden" class="hidden" name="id" value="<%$TicketObj->Id%>" /> -<&| /Widgets/TitleBox,title => loc('Modify dates for ticket # [_1]', $TicketObj->Id), class=> 'ticket-info-dates' &> +<&| /Widgets/TitleBox,title => loc('Modify dates for ticket #[_1]', $TicketObj->Id), class=> 'ticket-info-dates' &> <& Elements/EditDates, TicketObj => $TicketObj &> </&> <& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes') &> </form> +% $m->callback(CallbackName => 'AfterForm', ARGSRef => \%ARGS, Ticket => $TicketObj); <%INIT> diff --git a/rt/share/html/Ticket/ModifyLinks.html b/rt/share/html/Ticket/ModifyLinks.html index eda09c5..59f7141 100755 --- a/rt/share/html/Ticket/ModifyLinks.html +++ b/rt/share/html/Ticket/ModifyLinks.html @@ -57,23 +57,31 @@ % 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'); <&| /Widgets/TitleBox, title => loc('Edit Links'), class=>'ticket-info-links', @extra &> -<& /Elements/EditLinks, Object => $Ticket, Merge => 1 &> +<& /Elements/EditLinks, Object => $Ticket &> </&> -<& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes') &> -</form> +<&| /Widgets/TitleBox, title => loc('Merge'), class=>'ticket-info-merge' &> +<& Elements/EditMerge, Ticket => $Ticket, %ARGS &> +</&> +<& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes') &> +</form> +% $m->callback(CallbackName => 'AfterForm', ARGSRef => \%ARGS, Ticket => $Ticket); <%INIT> - my $Ticket = LoadTicket($id); my @results; $m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS, Results => \@results ); push @results, ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS ); +push @results, ProcessObjectCustomFieldUpdates( TicketObj => $Ticket, ARGSRef => \%ARGS ); $Ticket->ApplyTransactionBatch; - + +MaybeRedirectForResults( + Actions => \@results, + Arguments => { id => $id }, +); </%INIT> diff --git a/rt/share/html/Ticket/ModifyPeople.html b/rt/share/html/Ticket/ModifyPeople.html index 93f616a..f216ec8 100755 --- a/rt/share/html/Ticket/ModifyPeople.html +++ b/rt/share/html/Ticket/ModifyPeople.html @@ -51,7 +51,7 @@ % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket); <& /Elements/ListActions, actions => \@results &> -<form method="post" action="ModifyPeople.html"> +<form method="post" action="ModifyPeople.html" name="TicketPeople"> <input type="submit" name="SubmitTicket" value="Save Changes" style="display:none"> <input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" /> % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); @@ -60,8 +60,7 @@ </&> <&| /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. +<&|/l&>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> @@ -77,6 +76,8 @@ <& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &> </form> +% $m->callback(CallbackName => 'AfterForm', ARGSRef => \%ARGS, Ticket => $Ticket); + <%INIT> my @results; @@ -101,6 +102,8 @@ $Ticket->SquelchMailTo($_) unless ($OnlySearchForPeople or $OnlySearchForGroup) { push @results, ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS); push @results, ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS); + push @results, ProcessObjectCustomFieldUpdates( TicketObj => $Ticket, ARGSRef => \%ARGS ); + $Ticket->ApplyTransactionBatch; } diff --git a/rt/share/html/Ticket/Reminders.html b/rt/share/html/Ticket/Reminders.html index b9cefe6..892eca7 100755 --- a/rt/share/html/Ticket/Reminders.html +++ b/rt/share/html/Ticket/Reminders.html @@ -49,14 +49,15 @@ <& /Elements/Tabs &> % $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Ticket => $Ticket); + +<& /Elements/ListActions, actions => \@actions &> -<& /Elements/ListActions, actions => \@results &> <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 &> +<& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 1, Edit => 1, ShowSave => 0 &> </&> <& /Elements/Submit, Label => loc('Save Changes') &> @@ -66,7 +67,7 @@ <%INIT> my $Ticket = LoadTicket($id); -my @results = ProcessTicketReminders( TicketObj => $Ticket, ARGSRef => \%ARGS ); +my @actions = 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 e7d496e..bdb2119 100644 --- a/rt/share/html/Ticket/ShowEmailRecord.html +++ b/rt/share/html/Ticket/ShowEmailRecord.html @@ -50,10 +50,16 @@ $Attachment => undef $Transaction => undef </%ARGS> <%INIT> +my $plain_text_mono + = RT->Config->Get( 'PlainTextMono', $session{'CurrentUser'} ); +my $use_brs = !$plain_text_mono; + my $show_content = sub { my $attach = shift; if ( $attach->ContentType =~ m{^(?:text|message)/}i ) { - $m->out( $m->interp->apply_escapes( $attach->Content, 'h' ) ); + my $content = $m->interp->apply_escapes( $attach->Content, 'h' ); + $content =~ s{(\r?\n)}{<br />}g if $use_brs; + $m->out( $content ); return; } my $href = RT->Config->Get('WebPath') .'/Ticket/Attachment/' @@ -65,9 +71,15 @@ my $show_content = sub { my $show; $show = sub { my $attach = shift; - $m->out( '<div id="body"><pre style="padding: 2em;">' ); - $m->out( $m->interp->apply_escapes( $attach->Headers, 'h' ) ); - $m->out( "\n\n" ); + $m->out('<div id="body">'); + $m->out('<div class="plain-text-white-space">') if $plain_text_mono; + + my $headers = $m->interp->apply_escapes( $attach->Headers, 'h' ); + $headers =~ s{(\r?\n)}{<br />}g if $use_brs; + $m->out( $headers ); + + $m->out( $use_brs ? "<br /><br />" : "\n\n" ); + if ( $attach->ContentType =~ m{^multipart/}i ) { my $children = $attach->Children; while ( my $child = $children->Next ) { @@ -76,21 +88,44 @@ $show = sub { } else { $show_content->( $attach ); } - $m->out( '</pre></div>' ); + $m->out('</div>') if $plain_text_mono; + $m->out('</div>'); }; +# Set error for error message below. Abort doesn't display well +# because ShowEmailRecord doesn't use the standard RT menus +# and headers. + +my ($title, $error); + 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)); +$AttachmentObj->Load($Attachment); + +if ( not $AttachmentObj->id + or not $AttachmentObj->TransactionId() == $Transaction ) { + $title = loc("Error loading attachment"); + $error = loc("Attachment '[_1]' could not be loaded", $Attachment); +} +elsif ( not $AttachmentObj->TransactionObj->CurrentUserCanSee("Transaction")){ + $title = loc("Permission Denied"); + $error = loc("Permission Denied"); } -unless ($AttachmentObj->TransactionId() == $Transaction ) { - Abort(loc("Attachment '[_1]' could not be loaded", $Attachment)); +else{ + $title = loc("Email Source for Ticket [_1], Attachment [_2]", + $AttachmentObj->TransactionObj->ObjectId, + $AttachmentObj->Id); } </%INIT> -<& /Elements/Header, ShowBar => 0 &> -% $show->( $AttachmentObj ); +<& /Elements/Header, ShowBar => 0, Title => $title &> +% if ( $error ){ +<div id="body"><div class="error"> +<% $error %> +</div></div> +% } +% else{ +% $show->( $AttachmentObj ); +% } </body> </html> % $m->abort; diff --git a/rt/share/html/Ticket/Update.html b/rt/share/html/Ticket/Update.html index c4e8c25..8d3c9a4 100755 --- a/rt/share/html/Ticket/Update.html +++ b/rt/share/html/Ticket/Update.html @@ -56,9 +56,10 @@ % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS, Ticket => $TicketObj, CanRespond => $CanRespond, CanComment => $CanComment, ResponseDefault => $ResponseDefault, CommentDefault => $CommentDefault ); <input type="hidden" class="hidden" name="QuoteTransaction" value="<% $ARGS{QuoteTransaction}||'' %>" /> <input type="hidden" class="hidden" name="DefaultStatus" value="<% $DefaultStatus ||''%>" /> -<input type="hidden" class="hidden" name="Action" value="<% $ARGS{Action}||'' %>" /> +<input type="hidden" class="hidden" name="Action" value="<% $Action %>" /> +<input type="hidden" class="hidden" name="Token" value="<% $ARGS{'Token'} %>" /> -<& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> +<& /Elements/Crypt/SignEncryptWidget:ShowIssues, self => $gnupg_widget &> <div id="ticket-update-metadata"> <&|/Widgets/TitleBox, title => loc('Ticket and Transaction') &> @@ -88,16 +89,8 @@ <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')); + jQuery("input[name=TxnSendMailTo]").filter( function() { return this.value == ev.target.value; } ).prop("checked",jQuery(ev.target).prop('checked')); }); }); </script> @@ -127,13 +120,11 @@ function changeStatus() { InTable => 1, fields => [ { name => 'Status', - comp => '/Elements/SelectStatus', + comp => '/Ticket/Elements/SelectStatus', args => { Name => 'Status', - DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)), - Default => $ARGS{'Status'} || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus), + Default => $DefaultStatus, TicketObj => $TicketObj, - QueueObj => $TicketObj->QueueObj, onchange => 'changeStatus()' }, }, @@ -151,7 +142,7 @@ function changeStatus() { Name => "Owner", TicketObj => $TicketObj, QueueObj => $TicketObj->QueueObj, - DefaultLabel => loc("[_1] (Unchanged)", $m->scomp('/Elements/ShowUser', User => $TicketObj->OwnerObj)), + DefaultLabel => loc("[_1] (Unchanged)", $TicketObj->OwnerObj->Format), Default => $ARGS{'Owner'} } }, @@ -160,7 +151,6 @@ function changeStatus() { args => { Name => 'UpdateTimeWorked', Default => $ARGS{UpdateTimeWorked}||'', - InUnits => $ARGS{'UpdateTimeWorked-TimeUnits'}||'minutes', } }, ] @@ -172,7 +162,7 @@ changeStatus(); % $m->callback( %ARGS, CallbackName => 'AfterWorked', Ticket => $TicketObj ); -<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $TicketObj, AsTable => 1, KeepValue => 1 &> +<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $TicketObj, InTable => 1, KeepValue => 1, &> <!--</table>--> </&> @@ -187,7 +177,7 @@ changeStatus(); % if ( $gnupg_widget ) { <tr><td> </td><td> -<& /Elements/GnuPG/SignEncryptWidget, +<& /Elements/Crypt/SignEncryptWidget, self => $gnupg_widget, TicketObj => $TicketObj, &> @@ -255,6 +245,7 @@ my $TicketObj = LoadTicket($id); my @results; $m->callback( Ticket => $TicketObj, ARGSRef => \%ARGS, checks_failure => \$checks_failure, results => \@results, CallbackName => 'Initial' ); +$m->scomp( '/Articles/Elements/SubjectOverride', Ticket => $TicketObj, ARGSRef => \%ARGS, results => \@results ); unless($DefaultStatus){ $DefaultStatus=($ARGS{'Status'} ||$TicketObj->Status()); @@ -275,8 +266,8 @@ if ($Action ne 'Respond') { } my $type = $ARGS{'UpdateType'} ? $ARGS{'UpdateType'} : - lc $ARGS{'Action'} eq 'respond' ? 'response' : - lc $ARGS{'Action'} eq 'comment' ? 'private' : + lc $Action eq 'respond' ? 'response' : + lc $Action eq 'comment' ? 'private' : 'none' ; @@ -286,35 +277,30 @@ $CanRespond = 1 if ( $TicketObj->CurrentUserHasRight('ReplyToTicket') or $CanComment = 1 if ( $TicketObj->CurrentUserHasRight('CommentOnTicket') or $TicketObj->CurrentUserHasRight('ModifyTicket') ); - ProcessAttachments(ARGSRef => \%ARGS); -my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS ); -$m->comp( '/Elements/GnuPG/SignEncryptWidget:Process', +my %squelched = ProcessTransactionSquelching( \%ARGS ); +$ARGS{'SquelchMailTo'} = [keys %squelched] if keys %squelched; + +my $gnupg_widget = $m->comp('/Elements/Crypt/SignEncryptWidget:new', Arguments => \%ARGS ); +$m->comp( '/Elements/Crypt/SignEncryptWidget:Process', self => $gnupg_widget, TicketObj => $TicketObj, ); if ( $ARGS{'SubmitTicket'} ) { - my %squelched = ProcessTransactionSquelching( \%ARGS ); - $ARGS{'SquelchMailTo'} = [keys %squelched] if keys %squelched; - - my $CFs = $TicketObj->TransactionCustomFields; - my $ValidCFs = $m->comp( + my ($status, @msg) = $m->comp( '/Elements/ValidateCustomFields', - CustomFields => $CFs, - NamePrefix => "Object-RT::Transaction--CustomField-", + CustomFields => $TicketObj->TransactionCustomFields, + Object => RT::Transaction->new( $session{'CurrentUser'} ), ARGSRef => \%ARGS ); - unless ( $ValidCFs ) { + unless ( $status ) { + push @results, @msg; $checks_failure = 1; - while (my $CF = $CFs->Next) { - my $msg = $m->notes('InvalidField-' . $CF->Id) or next; - push @results, loc($CF->Name) . ': ' . $msg; - } } - my $status = $m->comp('/Elements/GnuPG/SignEncryptWidget:Check', + $status = $m->comp('/Elements/Crypt/SignEncryptWidget:Check', self => $gnupg_widget, TicketObj => $TicketObj, ); @@ -348,6 +334,6 @@ if ( !$checks_failure && !$skip_update && exists $ARGS{SubmitTicket} ) { <%ARGS> $id => undef -$Action => undef +$Action => '' $DefaultStatus => undef </%ARGS> |