summaryrefslogtreecommitdiff
path: root/rt/share/html/Ticket
diff options
context:
space:
mode:
Diffstat (limited to 'rt/share/html/Ticket')
-rwxr-xr-xrt/share/html/Ticket/Attachment/dhandler87
-rwxr-xr-xrt/share/html/Ticket/Create.html138
-rw-r--r--rt/share/html/Ticket/Crypt.html (renamed from rt/share/html/Ticket/GnuPG.html)2
-rwxr-xr-xrt/share/html/Ticket/Display.html45
-rw-r--r--rt/share/html/Ticket/Elements/AddAttachments17
-rwxr-xr-xrt/share/html/Ticket/Elements/AddWatchers22
-rw-r--r--rt/share/html/Ticket/Elements/Bookmark44
-rw-r--r--rt/share/html/Ticket/Elements/ClickToShowHistory11
-rw-r--r--rt/share/html/Ticket/Elements/DelayShowHistory (renamed from rt/share/html/Ticket/Elements/ShowUserEntry)36
-rwxr-xr-xrt/share/html/Ticket/Elements/EditBasics9
-rwxr-xr-xrt/share/html/Ticket/Elements/EditCustomFields63
-rwxr-xr-xrt/share/html/Ticket/Elements/EditDates1
-rw-r--r--rt/share/html/Ticket/Elements/EditMerge (renamed from rt/share/html/Ticket/Elements/FindTransactions)41
-rwxr-xr-xrt/share/html/Ticket/Elements/EditPeople30
-rw-r--r--rt/share/html/Ticket/Elements/EditTransactionCustomFields11
-rwxr-xr-xrt/share/html/Ticket/Elements/EditWatchers2
-rw-r--r--rt/share/html/Ticket/Elements/FindAttachments95
-rw-r--r--rt/share/html/Ticket/Elements/FoldStanzaJS50
-rw-r--r--rt/share/html/Ticket/Elements/LoadTextAttachments45
-rwxr-xr-xrt/share/html/Ticket/Elements/PreviewScrips28
-rw-r--r--rt/share/html/Ticket/Elements/Reminders72
-rw-r--r--[-rwxr-xr-x]rt/share/html/Ticket/Elements/SelectStatus (renamed from rt/share/html/Ticket/Elements/ShowDependencies)49
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowAttachments32
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowBasics7
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowCustomFields2
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowDates31
-rw-r--r--[-rwxr-xr-x]rt/share/html/Ticket/Elements/ShowDependencyStatus (renamed from rt/share/html/Ticket/Elements/ShowMembers)52
-rw-r--r--rt/share/html/Ticket/Elements/ShowGnuPGStatus177
-rw-r--r--rt/share/html/Ticket/Elements/ShowGroupMembers24
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowHistory161
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowMessageHeaders96
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowMessageStanza188
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowPeople1
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowRequestor40
-rw-r--r--rt/share/html/Ticket/Elements/ShowRequestorExtraInfo40
-rw-r--r--rt/share/html/Ticket/Elements/ShowRequestorTickets36
-rw-r--r--rt/share/html/Ticket/Elements/ShowSimplifiedRecipients15
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowSummary21
-rw-r--r--rt/share/html/Ticket/Elements/ShowTime4
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowTransaction240
-rw-r--r--rt/share/html/Ticket/Elements/ShowTransactionAttachments301
-rw-r--r--rt/share/html/Ticket/Elements/UpdateCc11
-rw-r--r--rt/share/html/Ticket/Forward.html35
-rw-r--r--rt/share/html/Ticket/Graphs/Elements/EditGraphProperties10
-rwxr-xr-xrt/share/html/Ticket/History.html13
-rwxr-xr-xrt/share/html/Ticket/Modify.html51
-rwxr-xr-xrt/share/html/Ticket/ModifyAll.html97
-rwxr-xr-xrt/share/html/Ticket/ModifyDates.html7
-rwxr-xr-xrt/share/html/Ticket/ModifyLinks.html18
-rwxr-xr-xrt/share/html/Ticket/ModifyPeople.html9
-rwxr-xr-xrt/share/html/Ticket/Reminders.html7
-rw-r--r--rt/share/html/Ticket/ShowEmailRecord.html59
-rwxr-xr-xrt/share/html/Ticket/Update.html62
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>&nbsp;</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">&nbsp;</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')
- : '&nbsp;';
-
- 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> &mdash; ";
-
- 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/&nbsp;/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>]&nbsp;";
- $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>]&nbsp;";
- }
- 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>&nbsp;</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>