summaryrefslogtreecommitdiff
path: root/rt/share/html/Ticket
diff options
context:
space:
mode:
Diffstat (limited to 'rt/share/html/Ticket')
-rw-r--r--rt/share/html/Ticket/Attachment/WithHeaders/dhandler80
-rwxr-xr-xrt/share/html/Ticket/Attachment/dhandler93
-rwxr-xr-xrt/share/html/Ticket/Create.html430
-rwxr-xr-xrt/share/html/Ticket/Display.html207
-rwxr-xr-xrt/share/html/Ticket/Elements/AddWatchers140
-rw-r--r--rt/share/html/Ticket/Elements/Bookmark93
-rwxr-xr-xrt/share/html/Ticket/Elements/BulkLinks195
-rwxr-xr-xrt/share/html/Ticket/Elements/EditBasics130
-rwxr-xr-xrt/share/html/Ticket/Elements/EditCustomFields108
-rwxr-xr-xrt/share/html/Ticket/Elements/EditDates77
-rwxr-xr-xrt/share/html/Ticket/Elements/EditPeople93
-rw-r--r--rt/share/html/Ticket/Elements/EditTransactionCustomFields81
-rwxr-xr-xrt/share/html/Ticket/Elements/EditWatchers79
-rw-r--r--rt/share/html/Ticket/Elements/FindAttachments95
-rw-r--r--rt/share/html/Ticket/Elements/LoadTextAttachments93
-rwxr-xr-xrt/share/html/Ticket/Elements/PreviewScrips235
-rw-r--r--rt/share/html/Ticket/Elements/Reminders178
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowAttachments104
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowBasics87
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowCustomFields51
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowDates91
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowDependencies65
-rw-r--r--rt/share/html/Ticket/Elements/ShowGnuPGStatus177
-rw-r--r--rt/share/html/Ticket/Elements/ShowGroupMembers65
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowHistory171
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowMembers69
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowMessageHeaders91
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowMessageStanza110
-rw-r--r--rt/share/html/Ticket/Elements/ShowParents63
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowPeople72
-rw-r--r--rt/share/html/Ticket/Elements/ShowPriority51
-rw-r--r--rt/share/html/Ticket/Elements/ShowQueue56
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowRequestor105
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowSummary117
-rw-r--r--rt/share/html/Ticket/Elements/ShowTime59
-rwxr-xr-xrt/share/html/Ticket/Elements/ShowTransaction216
-rw-r--r--rt/share/html/Ticket/Elements/ShowTransactionAttachments252
-rw-r--r--rt/share/html/Ticket/Elements/ShowUpdateStatus64
-rw-r--r--rt/share/html/Ticket/Elements/ShowUserEntry56
-rwxr-xr-xrt/share/html/Ticket/Elements/Tabs341
-rw-r--r--rt/share/html/Ticket/Elements/UpdateCc80
-rw-r--r--rt/share/html/Ticket/Forward.html123
-rw-r--r--rt/share/html/Ticket/GnuPG.html104
-rw-r--r--rt/share/html/Ticket/Graphs/Elements/EditGraphProperties167
-rw-r--r--rt/share/html/Ticket/Graphs/Elements/ShowGraph71
-rw-r--r--rt/share/html/Ticket/Graphs/Elements/ShowLegends73
-rw-r--r--rt/share/html/Ticket/Graphs/dhandler80
-rw-r--r--rt/share/html/Ticket/Graphs/index.html114
-rwxr-xr-xrt/share/html/Ticket/History.html91
-rwxr-xr-xrt/share/html/Ticket/Modify.html95
-rwxr-xr-xrt/share/html/Ticket/ModifyAll.html255
-rwxr-xr-xrt/share/html/Ticket/ModifyDates.html79
-rwxr-xr-xrt/share/html/Ticket/ModifyLinks.html85
-rwxr-xr-xrt/share/html/Ticket/ModifyPeople.html94
-rwxr-xr-xrt/share/html/Ticket/Reminders.html74
-rw-r--r--rt/share/html/Ticket/ShowEmailRecord.html96
-rwxr-xr-xrt/share/html/Ticket/Update.html269
57 files changed, 6890 insertions, 0 deletions
diff --git a/rt/share/html/Ticket/Attachment/WithHeaders/dhandler b/rt/share/html/Ticket/Attachment/WithHeaders/dhandler
new file mode 100644
index 0000000..18c39eb
--- /dev/null
+++ b/rt/share/html/Ticket/Attachment/WithHeaders/dhandler
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ # we don't need transaction id
+ my ($id) = $m->dhandler_arg =~ /^(\d+)/;
+ unless ( $id ) {
+ # wrong url format
+ Abort("Corrupted attachment URL");
+ }
+
+ my $AttachmentObj = new RT::Attachment( $session{'CurrentUser'} );
+ $AttachmentObj->Load( $id );
+ unless ( $AttachmentObj->id ) {
+ Abort("Couldn't load attachment #$id");
+ }
+
+ my $content_type = 'text/plain';
+ my $enc = $AttachmentObj->OriginalEncoding;
+ if ( $enc ) {
+ my $iana = Encode::find_encoding($enc);
+ $iana = $iana ? $iana->mime_name : $enc;
+ $content_type .= ";charset=$iana";
+ }
+
+ # XXX: should we check handle html here and integrate headers into html?
+ $r->content_type( $content_type );
+ $m->clear_buffer;
+ $m->out( $AttachmentObj->EncodedHeaders( $enc ) );
+ $m->out( "\n\n" );
+ $m->out( $AttachmentObj->OriginalContent );
+ $m->abort;
+</%perl>
+<%attr>
+AutoFlush => 0
+</%attr>
diff --git a/rt/share/html/Ticket/Attachment/dhandler b/rt/share/html/Ticket/Attachment/dhandler
new file mode 100755
index 0000000..d4d556b
--- /dev/null
+++ b/rt/share/html/Ticket/Attachment/dhandler
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ my ($ticket, $trans,$attach, $filename);
+ my $arg = $m->dhandler_arg; # get rest of path
+ if ($arg =~ '^(\d+)/(\d+)') {
+ $trans = $1;
+ $attach = $2;
+ }
+ else {
+ Abort("Corrupted attachment URL.");
+ }
+ my $AttachmentObj = new RT::Attachment($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");
+
+ }
+
+ my $content_type = $AttachmentObj->ContentType || 'text/plain';
+
+ unless (RT->Config->Get('TrustHTMLAttachments')) {
+ $content_type = 'text/plain' if ($content_type =~ /^text\/html/i);
+ }
+
+ if (my $enc = $AttachmentObj->OriginalEncoding) {
+ my $iana = Encode::find_encoding( $enc );
+ $iana = $iana? $iana->mime_name : $enc;
+ $content_type .= ";charset=$iana";
+ }
+
+ # unless (RT->Config->Get('TrustMIMEAttachments')) {
+ # $content_type = 'application/octet-stream';
+ # }
+
+ $r->content_type( $content_type );
+ $m->clear_buffer();
+ $m->out($AttachmentObj->OriginalContent);
+ $m->abort;
+</%perl>
+<%attr>
+AutoFlush => 0
+</%attr>
diff --git a/rt/share/html/Ticket/Create.html b/rt/share/html/Ticket/Create.html
new file mode 100755
index 0000000..28b6556
--- /dev/null
+++ b/rt/share/html/Ticket/Create.html
@@ -0,0 +1,430 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header,
+ Title => $title,
+ onload => "function () { hide(document.getElementById('Ticket-Create-details')) }" &>
+<& /Elements/Tabs,
+ current_toptab => "Ticket/Create.html",
+ Title => $title,
+ actions => $actions &>
+<& /Elements/ListActions, actions => \@results &>
+<form action="<% RT->Config->Get('WebPath') %>/Ticket/Create.html" method="post" enctype="multipart/form-data" name="TicketCreate">
+<input type="hidden" class="hidden" name="id" value="new" />
+% $m->callback( CallbackName => 'FormStart', QueueObj => $QueueObj, ARGSRef => \%ARGS );
+% if ($gnupg_widget) {
+<& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &>
+% }
+<div id="Ticket-Create-basics">
+<a name="basics"></a>
+<&| /Widgets/TitleBox, title => $title &>
+<table border="0" cellpadding="0" cellspacing="0">
+<tr><td class="label"><&|/l&>Queue</&>:</td>
+<td class="value"><& Elements/ShowQueue, QueueObj => $QueueObj &>
+<input type="hidden" class="hidden" name="Queue" value="<% $QueueObj->Name %>" />
+</td>
+<td class="label"><&|/l&>Status</&>:
+</td>
+<td class="value">
+<& /Elements/SelectStatus, Name => "Status", Default => $ARGS{Status}||'new', DefaultValue => 0, SkipDeleted => 1 &>
+</td>
+<td class="label">
+<&|/l&>Owner</&>:
+</td>
+<td class="value">
+<& /Elements/SelectOwner, Name => "Owner", QueueObj => $QueueObj, Default => $ARGS{Owner}||$RT::Nobody->Id, DefaultValue => 0 &>
+</td>
+% $m->callback( CallbackName => 'AfterOwner', ARGSRef => \%ARGS );
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Requestors</&>:
+</td>
+<td class="value" colspan="5">
+<& /Elements/EmailInput, Name => 'Requestors', Size => '40', Default => $ARGS{Requestors} || $session{CurrentUser}->EmailAddress &>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Cc</&>:
+</td>
+<td class="value" colspan="3"><& /Elements/EmailInput, Name => 'Cc', Size => '40', Default => $ARGS{Cc} &></td>
+<td class="comment" colspan="2"><i><font size="-2">
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <strong>will</strong> receive future updates.)</&></font></i>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Admin Cc</&>:
+</td>
+<td class="value" colspan="3"><& /Elements/EmailInput, Name => 'AdminCc', Size => '40', Default => $ARGS{AdminCc} &></td>
+<td class="comment" colspan="2"><i><font size="-2">
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <strong>will</strong> receive future updates.)</&></font></i>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Subject</&>:
+</td>
+<td class="value" colspan="5">
+<input name="Subject" size="60" maxsize="200" value="<%$ARGS{Subject} || ''%>" />
+</td>
+</tr>
+<tr>
+<td colspan="6">
+<& /Ticket/Elements/EditCustomFields, %ARGS, QueueObj => $QueueObj &>
+</td>
+</tr>
+<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj &>
+<tr>
+% if (exists $session{'Attachments'}) {
+<td class="label">
+<&|/l&>Attached file</&>:
+</td>
+<td colspan="5">
+<&|/l&>Check box to delete</&><br />
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
+% } # end of foreach
+</td>
+</tr>
+<tr>
+% } # end of if
+<td class="label">
+<&|/l&>Attach file</&>:
+</td>
+<td class="value" colspan="5">
+<input type="file" name="Attach" />
+<input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" />
+</td>
+</tr>
+
+% if ( $gnupg_widget ) {
+<tr><td>&nbsp;</td><td colspan="5">
+<& /Elements/GnuPG/SignEncryptWidget, self => $gnupg_widget, QueueObj => $QueueObj &>
+</td></tr>
+% }
+
+<tr>
+<td colspan="6">
+<&|/l&>Describe the issue below</&>:<br />
+% $m->callback( %ARGS, QueueObj => $QueueObj, CallbackName => 'BeforeMessageBox' );
+% if (exists $ARGS{Content}) {
+<& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => 0 &>
+% } else {
+<& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &>
+%}
+
+<br />
+</td>
+</tr>
+</table>
+</&>
+<& /Elements/Submit, Label => loc("Create")&>
+</div>
+
+<div id="Ticket-Create-details">
+<a name="details"></a>
+<table width="100%" border="0">
+<tr>
+<td width="50%" valign="top" class="boxcontainer">
+ <div class="ticket-info-basics">
+ <&| /Widgets/TitleBox, title => loc('The Basics'),
+ title_class=> 'inverse',
+ color => "#993333" &>
+<table border="0">
+<tr><td class="label"><&|/l&>Priority</&>:</td>
+<td><& /Elements/SelectPriority,
+ Name => "InitialPriority",
+ Default => $ARGS{InitialPriority} ? $ARGS{InitialPriority} : $QueueObj->InitialPriority,
+&></td></tr>
+<tr><td class="label"><&|/l&>Final Priority</&>:</td>
+<td><& /Elements/SelectPriority,
+ Name => "FinalPriority",
+ Default => $ARGS{FinalPriority} ? $ARGS{FinalPriority} : $QueueObj->FinalPriority,
+&></td></tr>
+<tr><td class="label"><&|/l&>Time Estimated</&>:</td>
+<td>
+<& /Elements/EditTimeValue, Name => 'TimeEstimated', Default => $ARGS{TimeEstimated} || '', InUnits => $ARGS{'TimeEstimated-TimeUnits'} &>
+
+</td></tr>
+<tr><td class="label"><&|/l&>Time Worked</&>:</td>
+<td>
+<& /Elements/EditTimeValue, Name => 'TimeWorked', Default => $ARGS{TimeWorked} || '', InUnits => $ARGS{'TimeWorked-TimeUnits'} &>
+</td></tr>
+<tr>
+<td class="label"><&|/l&>Time Left</&>:</td>
+<td>
+<& /Elements/EditTimeValue, Name => 'TimeLeft', Default => $ARGS{TimeLeft} || '', InUnits => $ARGS{'TimeLeft-TimeUnits'} &>
+</td></tr>
+</table>
+</&>
+<br />
+<div class="ticket-info-dates">
+<&|/Widgets/TitleBox, title => loc("Dates"),
+ 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>
+</table>
+</&>
+</div>
+</div>
+<br />
+</td>
+
+<td valign="top" class="boxcontainer">
+<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>
+
+
+</table>
+</&>
+</div>
+<br />
+
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Label => loc("Create") &>
+</div>
+</form>
+
+<%INIT>
+$m->callback( CallbackName => "Init", ARGSRef => \%ARGS );
+my $Queue = $ARGS{Queue};
+
+my $CloneTicketObj;
+if ($CloneTicket) {
+ $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} );
+ $CloneTicketObj->Load($CloneTicket)
+ or Abort( loc("Ticket could not be loaded") );
+
+ my $clone = {
+ Requestors => join( ',', $CloneTicketObj->RequestorAddresses ),
+ Cc => join( ',', $CloneTicketObj->CcAddresses ),
+ AdminCc => join( ',', $CloneTicketObj->AdminCcAddresses ),
+ InitialPriority => $CloneTicketObj->Priority,
+ };
+
+ $clone->{$_} = $CloneTicketObj->$_()
+ for qw/Owner Subject FinalPriority TimeEstimated TimeWorked
+ Status TimeLeft/;
+
+ $clone->{$_} = $CloneTicketObj->$_->AsString
+ for grep { $CloneTicketObj->$_->Unix }
+ 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;
+ while ( my $refer = $refers->Next ) {
+ push @refers, $refer->LocalTarget;
+ }
+ $clone->{'new-RefersTo'} = join ' ', @refers;
+
+ my $refers_by = $CloneTicketObj->ReferredToBy;
+ while ( my $refer_by = $refers_by->Next ) {
+ push @refers_by, $refer_by->LocalBase;
+ }
+ $clone->{'RefersTo-new'} = join ' ', @refers_by;
+ if (0) { # Temporarily disabled
+ my $depends = $CloneTicketObj->DependsOn;
+ while ( my $depend = $depends->Next ) {
+ push @depends, $depend->LocalTarget;
+ }
+ $clone->{'new-DependsOn'} = join ' ', @depends;
+
+ my $depends_by = $CloneTicketObj->DependedOnBy;
+ while ( my $depend_by = $depends_by->Next ) {
+ push @depends_by, $depend_by->LocalBase;
+ }
+ $clone->{'DependsOn-new'} = join ' ', @depends_by;
+
+ while ( my $member = $members->Next ) {
+ push @members, $member->LocalBase;
+ }
+ $clone->{'MemberOf-new'} = join ' ', @members;
+
+ my $members_of = $CloneTicketObj->MemberOf;
+ while ( my $member_of = $members_of->Next ) {
+ push @members_of, $member_of->LocalTarget;
+ }
+ $clone->{'new-MemberOf'} = join ' ', @members_of;
+
+ }
+
+ my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields();
+ while ( my $cf = $cfs->Next ) {
+ my $cf_id = $cf->id;
+ my $cf_values = $CloneTicketObj->CustomFieldValues( $cf->id );
+ my @cf_values;
+ while ( my $cf_value = $cf_values->Next ) {
+ push @cf_values, $cf_value->Content;
+ }
+ $clone->{"Object-RT::Ticket--CustomField-$cf_id-Value"} = join "\n",
+ @cf_values;
+ }
+
+ for ( keys %$clone ) {
+ $ARGS{$_} = $clone->{$_} if not defined $ARGS{$_};
+ }
+
+}
+
+my @results;
+
+my $title = loc("Create a new ticket");
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded."));
+
+$m->callback( QueueObj => $QueueObj, title => \$title, results => \@results, ARGSRef => \%ARGS );
+
+$QueueObj->Disabled && Abort(loc("Cannot create tickets in a disabled queue."));
+
+my $CFs = $QueueObj->TicketCustomFields();
+
+my $ValidCFs = $m->comp(
+ '/Elements/ValidateCustomFields',
+ CustomFields => $CFs,
+ ARGSRef => \%ARGS
+);
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+ if ($key =~ m/^DeleteAttach-(.+)$/) {
+ delete $session{'Attachments'}{$1};
+ }
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+# }}}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) { # attachment?
+ my $attachment = MakeMIMEEntity(
+ AttachmentFieldName => 'Attach'
+ );
+
+ my $file_path = Encode::decode_utf8("$ARGS{'Attach'}");
+ $session{'Attachments'} = {
+ %{$session{'Attachments'} || {}},
+ $file_path => $attachment,
+ };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'id'} eq 'new') {
+ delete $session{'Attachments'};
+}
+
+my $checks_failure = 0;
+
+my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS );
+$m->comp( '/Elements/GnuPG/SignEncryptWidget:Process',
+ self => $gnupg_widget,
+ QueueObj => $QueueObj,
+);
+
+
+if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) {
+ my $status = $m->comp('/Elements/GnuPG/SignEncryptWidget:Check',
+ self => $gnupg_widget,
+ Operation => 'Create',
+ QueueObj => $QueueObj,
+ );
+ $checks_failure = 1 unless $status;
+}
+
+my $skip_create = 0;
+$m->callback( CallbackName => 'BeforeCreate', ARGSRef => \%ARGS, skip_create => \$skip_create,
+ checks_failure => $checks_failure, results => \@results );
+
+if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} eq 'new')) { # new ticket?
+ if ( $ValidCFs && !$checks_failure && !$skip_create ) {
+ $m->comp('Display.html', %ARGS);
+ $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;
+ }
+ }
+}
+
+my $actions = {
+ A => {
+ html => q[<a href="#basics" onclick="return switchVisibility('Ticket-Create-basics','Ticket-Create-details');">] . loc('Show basics') . q[</a>],
+ },
+ B => {
+ html => q[<a href="#details" onclick="return switchVisibility('Ticket-Create-details','Ticket-Create-basics');">] . loc('Show details') . q[</a>],
+ },
+};
+</%INIT>
+
+<%ARGS>
+$DependsOn => undef
+$DependedOnBy => undef
+$MemberOf => undef
+$QuoteTransaction => undef
+$CloneTicket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Display.html b/rt/share/html/Ticket/Display.html
new file mode 100755
index 0000000..f8eaf39
--- /dev/null
+++ b/rt/share/html/Ticket/Display.html
@@ -0,0 +1,207 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header,
+ Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject),
+ LinkRel => \%link_rel &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ current_tab => 'Ticket/Display.html?id='.$TicketObj->id,
+ Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', %ARGS, Actions => \@Actions, ARGSRef => \%ARGS, Ticket => $TicketObj);
+
+<& /Elements/ListActions, actions => \@Actions &>
+<& Elements/ShowUpdateStatus, Ticket => $TicketObj &>
+
+% $m->callback( %ARGS, Ticket => $TicketObj, CallbackName => 'BeforeShowSummary' );
+<div class="summary">
+<&| /Widgets/TitleBox, title => loc('Ticket metadata') &>
+<& /Ticket/Elements/ShowSummary, Ticket => $TicketObj, Attachments => $attachments &>
+</&>
+</div>
+<br />
+
+% $m->callback( Ticket => $TicketObj, %ARGS, CallbackName => 'BeforeShowHistory' );
+
+<& /Ticket/Elements/ShowHistory ,
+ Ticket => $TicketObj,
+ Tickets => $Tickets,
+ Collapsed => $ARGS{'Collapsed'},
+ ShowHeaders => $ARGS{'ShowHeaders'},
+ Attachments => $attachments,
+ AttachmentContent => $attachment_content
+&>
+
+% $m->callback( %ARGS,
+% Ticket => $TicketObj,
+% current_tab => 'Ticket/Display.html?id=' . $TicketObj->id,
+% CallbackName => 'AfterShowHistory',
+% );
+
+<%ARGS>
+$id => undef
+$TicketObj => undef
+$ShowHeaders => 0
+$Collapsed => undef
+</%ARGS>
+
+<%INIT>
+
+$m->callback( TicketObj => $TicketObj, ARGSRef => \%ARGS, CallbackName => 'Initial' );
+
+my (@Actions, $Tickets);
+
+
+unless ($id || $TicketObj) {
+ Abort('No ticket specified');
+}
+
+if ($ARGS{'id'} eq 'new') {
+ # {{{ Create a new ticket
+
+ my $Queue = new RT::Queue( $session{'CurrentUser'} );
+ $Queue->Load($ARGS{'Queue'});
+ unless ( $Queue->id ) {
+ Abort('Queue not found');
+ }
+
+ unless ( $Queue->CurrentUserHasRight('CreateTicket') ) {
+ Abort('You have no permission to create tickets in that queue.');
+ }
+
+ ($TicketObj, @Actions) = CreateTicket(
+ Attachments => delete $session{'Attachments'},
+ %ARGS,
+ );
+ unless ( $TicketObj->CurrentUserHasRight('ShowTicket') ) {
+ Abort("No permission to view newly created ticket #".$TicketObj->id.".");
+ }
+ # }}}
+} else {
+ $TicketObj ||= LoadTicket($ARGS{'id'});
+
+ $m->callback( CallbackName => 'BeforeProcessArguments',
+ TicketObj => $TicketObj, Tickets => $Tickets,
+ ActionsRef => \@Actions, ARGSRef => \%ARGS );
+ if ( defined $ARGS{'Action'} ) {
+ if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) {
+ my $action = $1;
+ my ($res, $msg) = $TicketObj->$action();
+ push(@Actions, $msg);
+ }
+ }
+
+ $m->callback(CallbackName => 'ProcessArguments',
+ Ticket => $TicketObj,
+ ARGSRef => \%ARGS,
+ Actions => \@Actions);
+
+ $ARGS{UpdateAttachments} = $session{'Attachments'};
+ push @Actions,
+ ProcessUpdateMessage(
+ ARGSRef => \%ARGS,
+ Actions => \@Actions,
+ TicketObj => $TicketObj,
+ );
+ delete $session{'Attachments'};
+
+ #Process status updates
+ push @Actions, ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj );
+ push @Actions, ProcessTicketBasics( ARGSRef => \%ARGS, TicketObj => $TicketObj );
+ push @Actions, ProcessTicketLinks( ARGSRef => \%ARGS, TicketObj => $TicketObj );
+ push @Actions, ProcessTicketDates( ARGSRef => \%ARGS, TicketObj => $TicketObj );
+ push @Actions, ProcessObjectCustomFieldUpdates(ARGSRef => \%ARGS, TicketObj => $TicketObj );
+
+ # XXX: we shouldn't block actions here if user has no right to see the ticket,
+ # but we should allow him to see actions he has done
+ unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+ }
+ if ( $ARGS{'MarkAsSeen'} ) {
+ $TicketObj->SetAttribute(
+ Name => 'User-'. $TicketObj->CurrentUser->id .'-SeenUpTo',
+ Content => $TicketObj->LastUpdated,
+ );
+ push @Actions, loc('Marked all messages as seen');
+ }
+}
+
+$m->callback(
+ CallbackName => 'BeforeDisplay',
+ TicketObj => \$TicketObj,
+ Tickets => \$Tickets,
+ Actions => \@Actions,
+ ARGSRef => \%ARGS,
+);
+
+# This code does automatic redirection if any updates happen.
+
+if (@Actions) {
+
+ # We've done something, so we need to clear the decks to avoid
+ # resubmission on refresh.
+ # But we need to store Actions somewhere too, so we don't lose them.
+ my $key = Digest::MD5::md5_hex( rand(1024) );
+ push @{ $session{"Actions"}->{$key} ||= [] }, @Actions;
+ $session{'i'}++;
+ RT::Interface::Web::Redirect( RT->Config->Get('WebURL') . "Ticket/Display.html?id=" . $TicketObj->id . "&results=" . $key );
+
+}
+
+my $attachments = $m->comp('Elements/FindAttachments', Ticket => $TicketObj, Tickets => $Tickets);
+my $attachment_content = $m->comp('Elements/LoadTextAttachments', Ticket => $TicketObj);
+
+my %link_rel;
+if (defined $session{'tickets'} and ($ARGS{'Query'} or $session{'CurrentSearchHash'}->{'Query'})) {
+ my $item_map = $session{'tickets'}->ItemMap;
+ $link_rel{first} = "Ticket/Display.html?id=" . $item_map->{first} if $item_map->{$TicketObj->Id}{prev};
+ $link_rel{prev} = "Ticket/Display.html?id=" . $item_map->{$TicketObj->Id}{prev} if $item_map->{$TicketObj->Id}{prev};
+ $link_rel{next} = "Ticket/Display.html?id=" . $item_map->{$TicketObj->Id}{next} if $item_map->{$TicketObj->Id}{next};
+ $link_rel{last} = "Ticket/Display.html?id=" . $item_map->{last} if $item_map->{$TicketObj->Id}{next};
+}
+</%INIT>
diff --git a/rt/share/html/Ticket/Elements/AddWatchers b/rt/share/html/Ticket/Elements/AddWatchers
new file mode 100755
index 0000000..d2b222d
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/AddWatchers
@@ -0,0 +1,140 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<br />
+<br />
+
+<&|/l&>Add new watchers</&>:<br />
+
+<table>
+% if ($Users and $Users->Count) {
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Username</&>
+</td></tr>
+% while (my $u = $Users->Next ) {
+<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-". $u->PrincipalId &></td><td><& '/Elements/ShowUser', User => $u, style=>'verbose' &></td></tr>
+% }
+% }
+
+% if ($Groups and $Groups->Count) {
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/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>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Email</&>
+</td></tr>
+% my $counter = 4;
+% for my $email (@extras) {
+% $counter++;
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail".$counter &>
+</td><td>
+<input type="hidden" name="WatcherAddressEmail<%$counter%>" value="<%$email->address%>">
+<%$email->format%>
+</td></tr>
+% }
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail1" &>
+</td><td>
+<& /Elements/EmailInput, Name => 'WatcherAddressEmail1', Size => '20' &>
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail2" &>
+</td><td>
+<& /Elements/EmailInput, Name => 'WatcherAddressEmail2', Size => '20' &>
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail3" &>
+</td><td>
+<& /Elements/EmailInput, Name => 'WatcherAddressEmail3', Size => '20' &>
+</td></tr>
+</table>
+
+<%INIT>
+my ($Users, $Groups);
+
+if ($UserString) {
+ $Users = RT::Users->new($session{'CurrentUser'});
+ $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp);
+ $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);
+ }
+
+my @extras;
+for my $addr ( values %{$Ticket->TransactionAddresses} ) {
+ push @extras, $addr unless ($Ticket->IsWatcher( Email => $addr->address));
+}
+
+
+</%INIT>
+
+<%ARGS>
+$UserField => 'Name'
+$UserOp => '='
+$UserString => undef
+$GroupField => 'Name'
+$GroupOp => '='
+$GroupString => undef
+$PrivilegedOnly => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/Bookmark b/rt/share/html/Ticket/Elements/Bookmark
new file mode 100644
index 0000000..d857d38
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/Bookmark
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 $bookmarks = $session{'CurrentUser'}->UserObj->FirstAttribute('Bookmarks');
+$bookmarks = $bookmarks->Content if $bookmarks;
+$bookmarks ||= {};
+
+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);
+}
+
+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;
+}
+</%INIT>
+<%ARGS>
+$id
+$Toggle => 0
+</%ARGS>
+<span id="toggle-<% $id %>">
+% my $url = RT->Config->Get('WebPath') ."/Helpers/Toggle/TicketBookmark?id=". $id;
+<a align="right" href="<% $url %>" onclick="ahah('<% $url |n %>', 'toggle-<% $id |n %>'); return false;" >
+% if ( $bookmarked ) {
+<img src="<% RT->Config->Get('WebPath') %>/NoAuth/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" />
+% }
+</a>
+</span>
diff --git a/rt/share/html/Ticket/Elements/BulkLinks b/rt/share/html/Ticket/Elements/BulkLinks
new file mode 100755
index 0000000..7f87cef
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/BulkLinks
@@ -0,0 +1,195 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 width="100%">
+ <tr>
+ <td valign="top" width="50%">
+ <h3><&|/l&>Current Links</&></h3>
+<table>
+ <tr>
+ <td class="labeltop"><&|/l&>Depends on</&>:</td>
+ <td class="value">
+% if ( $hash{DependsOn} ) {
+% for my $link ( values %{$hash{DependsOn}} ) {
+ <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" />
+ <& /Elements/ShowLink, URI => $link->TargetURI &><br />
+% } }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Depended on by</&>:</td>
+ <td class="value">
+% if ( $hash{DependedOnBy} ) {
+% for my $link ( values %{$hash{DependedOnBy}} ) {
+ <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" />
+ <& /Elements/ShowLink, URI => $link->BaseURI &><br />
+% } }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Parents</&>:</td>
+ <td class="value">
+% if ( $hash{MemberOf} ) {
+% for my $link ( values %{$hash{MemberOf}} ) {
+ <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" />
+ <& /Elements/ShowLink, URI => $link->TargetURI &><br />
+% } }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Children</&>:</td>
+ <td class="value">
+% if ( $hash{Members} ) {
+% for my $link ( values %{$hash{Members}} ) {
+ <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" />
+ <& /Elements/ShowLink, URI => $link->BaseURI &><br />
+% } }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Refers to</&>:</td>
+ <td class="value">
+% if ( $hash{RefersTo} ) {
+% for my $link ( values %{$hash{RefersTo}} ) {
+ <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" />
+ <& /Elements/ShowLink, URI => $link->TargetURI &><br />
+% } }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Referred to by</&>:</td>
+ <td class="value">
+% if ( $hash{ReferredToBy} ) {
+% for my $link ( values %{$hash{ReferredToBy}} ) {
+% # Skip reminders
+% next if (UNIVERSAL::isa($link->BaseObj, 'RT::Ticket') && $link->BaseObj->Type eq 'reminder');
+ <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" />
+ <& /Elements/ShowLink, URI => $link->BaseURI &><br />
+% } }
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><i><&|/l&>(Check box to delete)</&></i></td>
+ </tr>
+</table>
+</td>
+<td valign="top">
+<h3><&|/l&>New Links</&></h3>
+<i><&|/l&>Enter tickets or URIs to link tickets to. Separate multiple entries with spaces.</&>
+</i><br />
+<table>
+ <tr>
+ <td class="label"><&|/l&>Merge into</&>:</td>
+ <td class="entry"><input name="Ticket-MergeInto" /> <i><&|/l&>(only one ticket)</&></i></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Depends on</&>:</td>
+ <td class="entry"><input name="Ticket-DependsOn" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Depended on by</&>:</td>
+ <td class="entry"><input name="DependsOn-Ticket" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Parents</&>:</td>
+ <td class="entry"><input name="Ticket-MemberOf" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Children</&>:</td>
+ <td class="entry"> <input name="MemberOf-Ticket" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Refers to</&>:</td>
+ <td class="entry"><input name="Ticket-RefersTo" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Referred to by</&>:</td>
+ <td class="entry"> <input name="RefersTo-Ticket" /></td>
+ </tr>
+</table>
+</td>
+</tr>
+</table>
+
+<%ARGS>
+$Tickets => undef
+</%ARGS>
+
+<%INIT>
+my %hash;
+if ( $Tickets && $Tickets->Count ) {
+ my $first_ticket = $Tickets->Next;
+ # we only show current links that eixst on all the tickets
+ for my $type ( qw/DependsOn DependedOnBy Members MemberOf RefersTo
+ ReferredToBy/ ) {
+ my $target_or_base =
+ $type =~ /DependsOn|MemberOf|RefersTo/ ? 'Target' : 'Base';
+ while ( my $link = $first_ticket->$type->Next ) {
+ $hash{$type}{$link->$target_or_base} = $link;
+ }
+ }
+
+ while ( my $ticket = $Tickets->Next ) {
+ for my $type ( qw/DependsOn DependedOnBy Members MemberOf RefersTo
+ ReferredToBy/ ) {
+ my $target_or_base =
+ $type =~ /DependsOn|MemberOf|RefersTo/ ? 'Target' : 'Base';
+ # if $hash{$type} is empty, no need to check any more
+ next unless $hash{$type} && keys %{$hash{$type}};
+ my %exists;
+ while ( my $link = $ticket->$type->Next ) {
+ $exists{$link->$target_or_base}++;
+ }
+
+ for ( keys %{$hash{$type}} ) {
+ delete $hash{$type}{$_} unless $exists{$_};
+ }
+ }
+ }
+}
+</%INIT>
diff --git a/rt/share/html/Ticket/Elements/EditBasics b/rt/share/html/Ticket/Elements/EditBasics
new file mode 100755
index 0000000..0dc4c6e
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/EditBasics
@@ -0,0 +1,130 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ <tr>
+ <td class="label"><&|/l&>Subject</&>:</td>
+ <td class="value"><input name="Subject" value="<%$TicketObj->Subject|h%>" size="50" /></td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Status</&>:</td>
+ <td class="value"><%$SelectStatus|n%></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Queue</&>:</td>
+ <td class="value"><%$SelectQueue|n%></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Owner</&>:</td>
+ <td class="value"><& /Elements/SelectOwner,
+ Name => 'Owner',
+ QueueObj => $TicketObj->QueueObj,
+ TicketObj => $TicketObj,
+ Default => $TicketObj->OwnerObj->Id,
+ DefaultValue => 0,
+ &></td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Time Estimated</&>:</td>
+ <td class="value">
+ <& /Elements/EditTimeValue,
+ Name => 'TimeEstimated',
+ Default => $TicketObj->TimeEstimated,
+ &>
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Time Worked</&>:</td>
+ <td class="value">
+ <& /Elements/EditTimeValue,
+ Name => 'TimeWorked',
+ Default => $TicketObj->TimeWorked,
+ &>
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Time Left</&>:</td>
+ <td class="value">
+ <& /Elements/EditTimeValue,
+ Name => 'TimeLeft',
+ Default => $TicketObj->TimeLeft,
+ &>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Priority</&>:</td>
+ <td class="value"><& /Elements/SelectPriority,
+ Default => $TicketObj->Priority,
+ &></td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Final Priority</&>:</td>
+ <td class="value"><& /Elements/SelectPriority,
+ Name => "FinalPriority",
+ Default => $TicketObj->FinalPriority,
+ &></td>
+ </tr>
+
+
+
+% $m->callback( CallbackName => 'EndOfList', TicketObj => $TicketObj, %ARGS );
+</table>
+
+<%INIT>
+#It's hard to do this inline, so we'll preload the html of the selectstatus in here.
+my $SelectStatus = $m->scomp("/Elements/SelectStatus", Name => 'Status', DefaultLabel => loc("[_1] (Unchanged)",loc($TicketObj->Status)));
+my $SelectQueue = $m->scomp("/Elements/SelectQueue", Name => 'Queue', Default =>$TicketObj->QueueObj->Id, ShowNullOption => 0);
+
+</%INIT>
+<%ARGS>
+
+$TicketObj => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/EditCustomFields b/rt/share/html/Ticket/Elements/EditCustomFields
new file mode 100755
index 0000000..c3a44ee
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/EditCustomFields
@@ -0,0 +1,108 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+% my $i = 0;
+% while ( my $CustomField = $CustomFields->Next ) {
+% next unless $CustomField->CurrentUserHasRight('ModifyCustomField');
+% $i++;
+% if ( $i % 2 ) {
+<tr>
+% }
+ <td class="cflabel">
+ <b><% loc($CustomField->Name) %></b><br />
+ <i><% $CustomField->FriendlyType %></i>
+ </td>
+ <td 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>
+% }
+ </td>
+
+% unless ( $i % 2 ) {
+</tr>
+% }
+
+% }
+
+%# close row if required
+% if ( $i % 2 ) {
+</tr>
+% }
+
+</table>
+<%INIT>
+my $CustomFields;
+
+if ($TicketObj && !$OnCreate) {
+ $CustomFields = $TicketObj->CustomFields();
+ $NamePrefix .= "Object-RT::Ticket-".$TicketObj->Id."-CustomField-";
+} else {
+ $CustomFields = $QueueObj->TicketCustomFields();
+ $NamePrefix .= "Object-RT::Ticket--CustomField-";
+}
+
+$m->callback( %ARGS, CallbackName => 'MassageCustomFields', CustomFields => $CustomFields );
+
+</%INIT>
+<%ARGS>
+$NamePrefix => ''
+$TicketObj => undef
+$QueueObj => undef
+$OnCreate => undef
+$DefaultsFromTopArguments => 1
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/EditDates b/rt/share/html/Ticket/Elements/EditDates
new file mode 100755
index 0000000..fc17cdb
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/EditDates
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ <tr>
+ <td class="label"><&|/l&>Starts</&>:</td>
+ <td class="entry"><& /Elements/SelectDate, menu_prefix => 'Starts', current => 0 &>
+ (<% $TicketObj->StartsObj->AsString %>)</td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Started</&>:</td>
+ <td class="entry"><& /Elements/SelectDate, menu_prefix => 'Started', current => 0 &> (<%$TicketObj->StartedObj->AsString %>)</td>
+ </tr>
+
+ <tr>
+ <td class="label">
+ <&|/l&>Last Contact</&>:
+ </td>
+ <td class="entry">
+ <& /Elements/SelectDate, menu_prefix => 'Told', current => 0 &> (<% $TicketObj->ToldObj->AsString %>)
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Due</&>:</td>
+ <td class="entry">
+ <& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>)
+ </td>
+ </tr>
+</table>
+<%ARGS>
+$TicketObj => undef
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/Elements/EditPeople b/rt/share/html/Ticket/Elements/EditPeople
new file mode 100755
index 0000000..abf121a
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/EditPeople
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 width="100%">
+<tr>
+<td valign="top">
+
+<h3><&|/l&>New watchers</&></h3>
+<&|/l&>Find people whose</&><br />
+<& /Elements/SelectUsers &>
+<input type="submit" class="button" name="OnlySearchForPeople" value="<&|/l&>Go!</&>" />
+<br />
+<&|/l&>Find groups whose</&><br />
+<& /Elements/SelectGroups &>
+<input type="submit" class="button" name="OnlySearchForGroup" value="<&|/l&>Go!</&>" />
+
+<& AddWatchers, Ticket => $Ticket, UserString => $UserString,
+ UserOp => $UserOp, UserField => $UserField,
+ 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>
+
+<&|/l&>Requestors</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Requestors &>
+
+<&|/l&>Cc</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Cc &>
+
+<&|/l&>Administrative Cc</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->AdminCc &>
+
+<i><&|/l&>(Check box to delete)</&></i><br />
+</td>
+</tr>
+</table>
+
+<%ARGS>
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
+$PrivilegedOnly => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/EditTransactionCustomFields b/rt/share/html/Ticket/Elements/EditTransactionCustomFields
new file mode 100644
index 0000000..8bf939d
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/EditTransactionCustomFields
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 ($CustomFields->Count) {
+% while (my $CF = $CustomFields->Next()) {
+% next unless $CF->CurrentUserHasRight('ModifyCustomField');
+<tr>
+<td class="label"><% loc($CF->Name) %>:</td>
+<td>
+<& /Elements/EditCustomField,
+ CustomField => $CF,
+ NamePrefix => $NamePrefix
+&>
+<em><% $CF->FriendlyType %></em>
+</td>
+</td></tr>
+% }
+% }
+
+<%INIT>
+my $CustomFields;
+
+if ($TicketObj) {
+ $CustomFields = $TicketObj->TransactionCustomFields();
+} else {
+ $CustomFields = $QueueObj->TicketTransactionCustomFields();
+}
+
+$m->callback( CallbackName => 'MassageTransactionCustomFields', CustomFields => $CustomFields );
+
+</%INIT>
+<%ARGS>
+$NamePrefix => "Object-RT::Transaction--CustomField-"
+$TicketObj => undef
+$QueueObj => undef
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/Elements/EditWatchers b/rt/share/html/Ticket/Elements/EditWatchers
new file mode 100755
index 0000000..6f05c69
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/EditWatchers
@@ -0,0 +1,79 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<ul>
+%# Print out a placeholder if there are none.
+% unless ( $Members->Count ) {
+<li><i><&|/l&>none</&></i></li>
+% }
+
+
+% 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 />
+% if ( $member->isa( 'RT::User' ) ) {
+<a href="<% RT->Config->Get('WebPath') %>/Admin/Users/Modify.html?id=<% $watcher->MemberId %>">
+<& /Elements/ShowUser, User => $member &></a>
+% if ($TicketObj and grep { $_->Content eq $member->EmailAddress } $TicketObj->SquelchMailTo) {
+<b><&|/l&>(Will not be sent email)</&></b>
+% }
+
+% } else {
+<a href="<% RT->Config->Get('WebPath') %>/Admin/Groups/Modify.html?id=<% $watcher->MemberId %>">
+<% $member->Name %></a>
+% }
+</li>
+% }
+</ul>
+<%INIT>
+my $Members = $Watchers->MembersObj;
+</%INIT>
+<%ARGS>
+$TicketObj => undef
+$Watchers => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/FindAttachments b/rt/share/html/Ticket/Elements/FindAttachments
new file mode 100644
index 0000000..1ce75fd
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/FindAttachments
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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/LoadTextAttachments b/rt/share/html/Ticket/Elements/LoadTextAttachments
new file mode 100644
index 0000000..84732b9
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/LoadTextAttachments
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 $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);
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/Elements/PreviewScrips b/rt/share/html/Ticket/Elements/PreviewScrips
new file mode 100755
index 0000000..7480ade
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/PreviewScrips
@@ -0,0 +1,235 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$TicketObj => undef
+
+</%args>
+<%init>
+my %squelch = $m->comp('SELF:SquelchRecipients', %ARGS);
+my $Object = $squelch{'Object'};
+my @non_recipients = @{ $squelch{'EmailAddresses'} };
+
+</%init>
+<h2><&|/l&>This message will be sent to...</&></h2>
+
+% if ( $Object and $Object->Scrips ) {
+<i><&|/l&>(Check boxes to disable notifications to the listed recipients)</&></i><br />
+
+% foreach my $scrip (@{$Object->Scrips->Prepared}) {
+% next unless $scrip->ActionObj->Action->isa('RT::Action::SendEmail');
+<b><% $scrip->Description || loc('Scrip #[_1]',$scrip->id) %></b><br />
+<&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)&>[_1] [_2] with template [_3]</&>
+<br />
+%foreach my $type qw(To Cc Bcc) {
+%my @addresses = $scrip->ActionObj->Action->$type();
+<ul>
+%foreach my $addr (@addresses) {
+<li> <b><%loc($type)%></b>: <input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-SquelchMailTo" value="<%$addr->address%>" /> <%$addr->address%>
+% }
+</ul>
+% }
+% if (RT->Config->Get('PreviewScripMessages')) {
+<textarea cols="80" rows="5">
+<%$scrip->ActionObj->TemplateObj->MIMEObj->as_string%>
+</textarea>
+% }
+% }
+% }
+<br />
+
+<h2><&|/l&>Messages about this ticket will not be sent to...</&></h2>
+<i><&|/l&>(Check boxes to enable notifications to the listed recipients)</&></i>
+<br />
+<ul>
+% foreach my $recipient (@non_recipients) {
+<li><input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-UnsquelchMailTo" value="<%$recipient->Content%>" />
+<% $recipient->Content %>
+% }
+</ul>
+<& /Elements/Submit, Name => 'UpdatePreview', Value => 'UpdatePreview', Label => loc('Save Changes')&>
+
+<%METHOD SquelchRecipients>
+<%ARGS>
+$TicketObj => undef
+</%ARGS>
+<%INIT>
+my $arg = 'Ticket-'.$TicketObj->Id.'-SquelchMailTo';
+my @squelchto = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
+
+foreach my $address (@squelchto) {
+ $TicketObj->SquelchMailTo($address) if ($address);
+}
+
+
+$arg = 'Ticket-'.$TicketObj->Id.'-UnsquelchMailTo';
+my @unsquelchto = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
+
+foreach my $address (@unsquelchto) {
+ $TicketObj->UnsquelchMailTo($address) if ($address);
+}
+
+
+my $action;
+
+if (($ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq 'response' ) || ($ARGS{'Action'} && $ARGS{'Action'} eq 'Respond' )) {
+ $action = 'Correspond';
+}
+else {
+ $action = 'Comment';
+}
+
+my $Message = MakeMIMEEntity(
+ Subject => $ARGS{'UpdateSubject'},
+ Body => $ARGS{'UpdateContent'},
+);
+
+my ( $Transaction, $Description, $Object ) = $TicketObj->$action(
+ CcMessageTo => $ARGS{'UpdateCc'},
+ BccMessageTo => $ARGS{'UpdateBcc'},
+ MIMEObj => $Message,
+ TimeTaken => $ARGS{'UpdateTimeWorked'},
+ DryRun => 1
+);
+unless ( $Transaction ) {
+ $RT::Logger->error("Coulfn't fire '$action' action: $Description");
+}
+
+
+return (Object => $Object, EmailAddresses => [$TicketObj->SquelchMailTo]);
+</%INIT>
+</%METHOD>
+
+<%METHOD GetRecipients>
+<%ARGS>
+$TicketObj
+</%ARGS>
+<%INIT>
+my $action;
+if ( ( $ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq 'response' )
+ || ( $ARGS{'Action'} && $ARGS{'Action'} eq 'Respond' ) )
+{
+ $action = 'Correspond';
+}
+else {
+ $action = 'Comment';
+}
+
+my $Message = MakeMIMEEntity(
+ Subject => $ARGS{'UpdateSubject'},
+ Body => $ARGS{'UpdateContent'},
+);
+
+my ( $id, $msg, $txn ) = $TicketObj->$action(
+ CcMessageTo => $ARGS{'UpdateCc'},
+ BccMessageTo => $ARGS{'UpdateBcc'},
+ MIMEObj => $Message,
+ TimeTaken => $ARGS{'UpdateTimeWorked'},
+ DryRun => 1
+);
+unless ( $id && $txn ) {
+ $RT::Logger->error("Couldn't fire '$action' action: $msg");
+ return ();
+}
+
+my @recipients;
+foreach my $scrip ( @{ $txn->Scrips->Prepared } ) {
+ my $action = $scrip->ActionObj->Action;
+ next unless $action->isa('RT::Action::SendEmail');
+
+ foreach my $type qw(To Cc Bcc) {
+ push @recipients, $action->$type();
+ }
+}
+return @recipients;
+</%INIT>
+</%METHOD>
+
+<%METHOD GetRecipientsOnCreate>
+<%INIT>
+my $action;
+my $Message = MakeMIMEEntity(
+ Subject => $ARGS{'Subject'},
+ Cc => $ARGS{'Cc'},
+ Body => $ARGS{'Content'},
+);
+
+my $TicketObj = RT::Ticket->new( $session{'CurrentUser'} );
+my ( $id, $txn, $msg ) = $TicketObj->Create(
+ Type => $ARGS{'Type'} || 'ticket',
+ Queue => $ARGS{'Queue'},
+ Owner => $ARGS{'Owner'},
+ Requestor => $ARGS{'Requestors'},
+ Cc => $ARGS{'Cc'},
+ AdminCc => $ARGS{'AdminCc'},
+ InitialPriority => $ARGS{'InitialPriority'},
+ FinalPriority => $ARGS{'FinalPriority'},
+ TimeLeft => $ARGS{'TimeLeft'},
+ TimeEstimated => $ARGS{'TimeEstimated'},
+ TimeWorked => $ARGS{'TimeWorked'},
+ Subject => $ARGS{'Subject'},
+ Status => $ARGS{'Status'},
+ MIMEObj => $Message,
+ DryRun => 1
+);
+unless ( $id && $txn ) {
+ $RT::Logger->error("Couldn't fire '$action' action: $msg");
+ return ();
+}
+
+my @recipients;
+foreach my $scrip ( @{ $txn->Scrips->Prepared } ) {
+ my $action = $scrip->ActionObj->Action;
+ next unless $action->isa('RT::Action::SendEmail');
+
+ foreach my $type qw(To Cc Bcc) {
+ push @recipients, $action->$type();
+ }
+}
+return @recipients;
+</%INIT>
+</%METHOD>
diff --git a/rt/share/html/Ticket/Elements/Reminders b/rt/share/html/Ticket/Elements/Reminders
new file mode 100644
index 0000000..14d61ef
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/Reminders
@@ -0,0 +1,178 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Ticket => undef
+$id => undef
+$ShowCompleted => 0
+$Edit => 0
+</%args>
+<%init>
+
+$Ticket = LoadTicket($id) if ($id);
+
+my $request_args = $m->request_args();
+
+my $reminder_collection = $Ticket->Reminders->Collection;
+
+if ( $request_args->{'update-reminders'} ) {
+ while ( my $reminder = $reminder_collection->Next ) {
+ if ( $reminder->Status ne 'resolved' && $request_args->{ 'Complete-Reminder-' . $reminder->id } ) {
+ $Ticket->Reminders->Resolve($reminder);
+ }
+ elsif ( $reminder->Status eq 'resolved' && !$request_args->{ 'Complete-Reminder-' . $reminder->id } ) {
+ $Ticket->Reminders->Open($reminder);
+ }
+
+ if ( exists( $request_args->{ 'Reminder-Subject-' . $reminder->id } ) && ( $reminder->Subject ne $request_args->{ 'Reminder-Subject-' . $reminder->id } )) {
+ $reminder->SetSubject( $request_args->{ 'Reminder-Subject-' . $reminder->id } ) ;
+ }
+
+ if ( exists( $request_args->{ 'Reminder-Owner-' . $reminder->id } ) && ( $reminder->Owner != $request_args->{ 'Reminder-Owner-' . $reminder->id } )) {
+ $reminder->SetOwner( $request_args->{ 'Reminder-Owner-' . $reminder->id } , "Force" ) ;
+ }
+
+ if ( exists( $request_args->{ 'Reminder-Due-' . $reminder->id } ) && ( $reminder->DueObj->Date ne $request_args->{ 'Reminder-Due-' . $reminder->id } )) {
+ $reminder->SetDue( $request_args->{ 'Reminder-Due-' . $reminder->id } ) ;
+ }
+ }
+}
+
+if ( $request_args->{'NewReminder-Subject'} ) {
+ my $due_obj = RT::Date->new( $session{'CurrentUser'} );
+ my $date = Time::ParseDate::parsedate(
+ $request_args->{'NewReminder-Due'},
+ UK => RT->Config->Get('DateDayBeforeMonth'),
+ PREFER_PAST => 0,
+ PREFER_FUTURE => 1
+ );
+ $due_obj->Set( Value => $date, Format => 'unix' );
+ my ( $add_id, $msg, $txnid ) = $Ticket->Reminders->Add(
+
+ Subject => $request_args->{'NewReminder-Subject'},
+ Owner => $request_args->{'NewReminder-Owner'},
+ Due => $due_obj->ISO
+ );
+}
+
+# We've made changes, let's reload our search
+
+$reminder_collection = $Ticket->Reminders->Collection;
+</%init>
+<input type="hidden" class="hidden" name="id" value="<% $Ticket->id %>" />
+<input type="hidden" class="hidden" name="update-reminders" value="1" />
+<div>
+% while (my $reminder = $reminder_collection->Next) {
+% if ($reminder->Status eq 'resolved' && !$ShowCompleted) {
+<input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" />
+% } elsif ($Edit) {
+<& SELF:EditEntry, Reminder => $reminder, Ticket => $Ticket &>
+% } else {
+<& SELF:ShowEntry, Reminder => $reminder, Ticket => $Ticket &>
+% }
+% }
+% if ($reminder_collection->Count) {
+<i><&|/l&>(Check box to delete)</&></i><br /><br />
+% }
+</div>
+<div>
+<&|/l&>New reminder:</&>
+<& SELF:NewReminder, Ticket => $Ticket &>
+<%method NewReminder>
+<%args>
+$Ticket
+</%args>
+<table>
+<tr class="input-row">
+<td class="label"><label class="horizontal" for="NewReminder-Subject" ><&|/l&>Subject</&>:</label></td>
+<td class="value">
+<input type="text" size="15" name="NewReminder-Subject" id="NewReminder-Subject" />
+</td>
+</tr>
+<tr class="input-row">
+<td class="label">
+<label class="horizontal" for="NewReminder-Owner" ><&|/l&>Owner</&>:</label></td><td class="value">
+<& /Elements/SelectOwner, Name => 'NewReminder-Owner', QueueObj => $Ticket->QueueObj, Default=>$session{'CurrentUser'}->id, DefaultValue => 0 &>
+</td>
+</tr>
+<tr class="input-row">
+<td class="label"><label class="horizontal" for="NewReminder-Due" ><&|/l&>Due</&>:</label></td>
+<td class="value">
+<& /Elements/SelectDate, Name => "NewReminder-Due", Default => "" &>
+</td>
+</tr>
+</table>
+</%method>
+<%method EditEntry>
+<%args>
+$Reminder
+$Ticket
+</%args>
+<input
+ type="checkbox"
+ name="Complete-Reminder-<%$Reminder->id%>"
+ <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' %>
+/>
+ <input type="text" size="15" name="Reminder-Subject-<% $Reminder->id %>" value="<%$Reminder->Subject%>" /> &bull;
+ <& /Elements/SelectOwner, Name => 'Reminder-Owner-'.$Reminder->id, Queue => $Ticket->QueueObj, Default => $Reminder->Owner, DefaultValue => 0 &>
+ <& /Elements/SelectDate, Name => 'Reminder-Due-'.$Reminder->id, Default => $Reminder->DueObj->Date &>
+ (<%$Reminder->DueObj->Unix>0 ? $Reminder->DueObj->AgeAsString : '' %>)<br />
+</%method>
+<%method ShowEntry>
+<%args>
+$Reminder
+$Ticket
+</%args>
+<input
+ type="checkbox"
+ name="Complete-Reminder-<%$Reminder->id%>"
+ <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' %>
+/>
+ <%$Reminder->Subject%> &bull;
+ <%$Reminder->OwnerObj->Name%>
+ <%$Reminder->DueObj->Unix>0 ? "&bull; ". $Reminder->DueObj->AgeAsString : '' |n%><br />
+</%method>
diff --git a/rt/share/html/Ticket/Elements/ShowAttachments b/rt/share/html/Ticket/Elements/ShowAttachments
new file mode 100755
index 0000000..72298d7
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowAttachments
@@ -0,0 +1,104 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 (keys %documents) {
+<&| /Widgets/TitleBox, title => loc('Attachments'),
+ title_class=> 'inverse',
+ class => 'ticket-info-attachments',
+ color => "#336699" &>
+
+% foreach my $key (keys %documents) {
+
+<%$key%><br />
+<ul>
+% foreach my $rev (@{$documents{$key}}) {
+
+<%PERL>
+my $size = $rev->ContentLength;
+
+if ($size) {
+ if ($size > 1024) {
+ $size = int($size/102.4)/10 . "k";
+ }
+ else {
+ $size = $size ."b";
+ }
+
+</%PERL>
+
+<li><font size="-2">
+<a href="<%RT->Config->Get('WebPath')%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | u%>">
+<&|/l, $rev->CreatedAsString, $size, $rev->CreatorObj->Name &>[_1] ([_2]) by [_3]</&>
+</a>
+</font></li>
+% }
+% }
+</ul>
+
+% }
+</&>
+
+% }
+
+<%INIT>
+
+# 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);
+
+my %documents;
+while ( my $attach = $Attachments->Next() ) {
+ next unless ($attach->Filename());
+ unshift( @{ $documents{ $attach->Filename } }, $attach );
+}
+
+</%INIT>
+<%ARGS>
+$Ticket => undef
+$Attachments => undef
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/Elements/ShowBasics b/rt/share/html/Ticket/Elements/ShowBasics
new file mode 100755
index 0000000..5dcbced
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowBasics
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ <tr>
+ <td class="label id"><&|/l&>Id</&>:</td>
+ <td class="value id"><%$Ticket->Id %></td>
+ </tr>
+ <tr>
+ <td class="label status"><&|/l&>Status</&>:</td>
+ <td class="value status"><% loc($Ticket->Status) %></td>
+ </tr>
+% if ($Ticket->TimeEstimated) {
+ <tr>
+ <td class="label time estimated"><&|/l&>Estimated</&>:</td>
+ <td class="value time estimated"><& ShowTime, minutes => $Ticket->TimeEstimated &></td>
+ </tr>
+% }
+% if ($Ticket->TimeWorked) {
+ <tr>
+ <td class="label time worked"><&|/l&>Worked</&>:</td>
+ <td class="value time worked"><& ShowTime, minutes => $Ticket->TimeWorked &></td>
+ </tr>
+% }
+% if ($Ticket->TimeLeft) {
+ <tr>
+ <td class="label time left"><&|/l&>Left</&>:</td>
+ <td class="value time left"><& ShowTime, minutes => $Ticket->TimeLeft &></td>
+ </tr>
+% }
+ <tr>
+ <td class="label priority"><&|/l&>Priority</&>:</td>
+ <td class="value priority"><& ShowPriority, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="label queue"><&|/l&>Queue</&>:</td>
+ <td class="value queue"><& ShowQueue, QueueObj => $Ticket->QueueObj &></td>
+ </tr>
+% $m->callback( %ARGS, CallbackName => 'EndOfList', TicketObj => $Ticket );
+</table>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowCustomFields b/rt/share/html/Ticket/Elements/ShowCustomFields
new file mode 100755
index 0000000..a836685
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowCustomFields
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/ShowCustomFields, Object => $Ticket &>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowDates b/rt/share/html/Ticket/Elements/ShowDates
new file mode 100755
index 0000000..d309907
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowDates
@@ -0,0 +1,91 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ <tr>
+ <td class="label date created"><&|/l&>Created</&>:</td>
+ <td class="value date created"><% $Ticket->CreatedObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date starts"><&|/l&>Starts</&>:</td>
+ <td class="value date starts"><% $Ticket->StartsObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date started"><&|/l&>Started</&>:</td>
+ <td class="value date started"><% $Ticket->StartedObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date told"><a href="<% RT->Config->Get('WebPath') %>/Ticket/Display.html?id=<% $Ticket->id %>&Action=SetTold"><&|/l&>Last Contact</&></a>:</td>
+ <td class="value date told"><% $Ticket->ToldObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date due"><&|/l&>Due</&>:</td>
+% my $due = $Ticket->DueObj;
+% if ( $due && $due->Unix > 0 && $due->Diff < 0 ) {
+ <td class="value date due"><span class="overdue"><% $due->AsString %></span></td>
+% } else {
+ <td class="value date due"><% $due->AsString %></td>
+% }
+ </tr>
+ <tr>
+ <td class="label date resolved"><&|/l&>Closed</&>:</td>
+ <td class="value date resolved"><% $Ticket->ResolvedObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date updated"><&|/l&>Updated</&>:</td>
+% my $UpdatedString = $Ticket->LastUpdated ? loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name) : loc("Never");
+% if ($UpdatedLink) {
+ <td class="value date updated"><a href="#lasttrans"><% $UpdatedString | h %></a></td>
+% } else {
+ <td class="value date updated"><% $UpdatedString | h %></td>
+% }
+ </tr>
+</table>
+<%ARGS>
+$Ticket => undef
+$UpdatedLink => 1
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowDependencies b/rt/share/html/Ticket/Elements/ShowDependencies
new file mode 100755
index 0000000..528be93
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowDependencies
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<&|/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>: (<%$member->OwnerObj->Name%>) <%$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>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
+[<%$member->Status%>]
+ <br />
+% }
+
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowGnuPGStatus b/rt/share/html/Ticket/Elements/ShowGnuPGStatus
new file mode 100644
index 0000000..08814aa
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowGnuPGStatus
@@ -0,0 +1,177 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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
new file mode 100644
index 0000000..a15f850
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowGroupMembers
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+%# 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 &><br />
+% }
+% my $Groups = $Group->GroupMembersObj( Recursively => $Recursively );
+% $Groups->LimitToUserDefinedGroups;
+% while (my $group = $Groups->Next) {
+<&|/l&>Group</&>: <% $group->Name %><br />
+% }
+
+<%ARGS>
+$Group => undef
+$Recursively => 0,
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowHistory b/rt/share/html/Ticket/Elements/ShowHistory
new file mode 100755
index 0000000..d859483
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowHistory
@@ -0,0 +1,171 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 = '';
+
+ if ($ShowHeaders) {
+ $titleright .= qq{<a href="$URIFile?id=} .
+ $Ticket->id.qq{">} .
+ loc("Brief headers") .
+ qq{</a> &mdash; };
+ $titleright .= q[<span class="selected">] . loc("Full headers") . "</span>";
+ }
+ else {
+ $titleright .= q[<span class="selected">] . loc("Brief headers") . "</span> &mdash; ";
+ $titleright .= qq{<a href="$URIFile?ShowHeaders=1;id=} .
+ $Ticket->id.qq{">} .
+ loc("Full headers") .
+ qq{</a>};
+ }
+ }
+</%perl>
+<div class="history">
+<& /Widgets/TitleBoxStart, title => $title, titleright_raw => $titleright &>
+% }
+
+<div id="ticket-history">
+<%perl>
+my @attachments = @{$Attachments->ItemsArrayRef()};
+my @attachment_content = @{$AttachmentContent->ItemsArrayRef()};
+
+while ( my $Transaction = $Transactions->Next ) {
+ my $skip = 0;
+ $m->callback(
+ %ARGS,
+ Transaction => $Transaction,
+ skip => \$skip,
+ CallbackName => 'SkipTransaction',
+ );
+ next if $skip;
+
+ $i++;
+
+ my @trans_attachments = grep { $_->TransactionId == $Transaction->Id } @attachments;
+
+ my $trans_content = {};
+ grep { ($_->TransactionId == $Transaction->Id ) && ($trans_content->{$_->Id} = $_) } @attachment_content;
+
+
+ my $IsLastTransaction = 0;
+ if ( $OldestFirst ) {
+ $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,
+ 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 $Transactions = new RT::Transactions($session{'CurrentUser'});
+if ($Tickets) {
+ while (my $t = $Tickets->Next) {
+ $Transactions->LimitToTicket($t->id);
+ }
+} else {
+ $Transactions = $Ticket->Transactions;
+}
+
+
+my $OldestFirst = RT->Config->Get( 'OldestTransactionsFirst', $session{'CurrentUser'} );
+my $SortOrder = $OldestFirst? 'ASC': 'DESC';
+$Transactions->OrderByCols( { FIELD => 'Created',
+ ORDER => $SortOrder },
+ { FIELD => 'id',
+ ORDER => $SortOrder },
+ );
+
+my $i;
+$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
+$Attachments => undef
+$AttachmentContent => undef
+$ShowHeaders => undef
+$ShowTitle => 1
+$ShowDisplayModes => 1
+$WarnUnsigned => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowMembers b/rt/share/html/Ticket/Elements/ShowMembers
new file mode 100755
index 0000000..dc570b5
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowMembers
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<ul>
+% while (my $link = $members->Next) {
+<li><& /Elements/ShowLink, URI => $link->BaseURI &><br />
+% if ($depth < 8) {
+<& /Ticket/Elements/ShowMembers, Ticket => $link->BaseObj, depth => ($depth+1) &>
+% }
+</li>
+% }
+</ul>
+
+<%INIT>
+
+return unless $Ticket;
+my $members = $Ticket->Members;
+return unless $members->Count;
+
+</%INIT>
+
+<%ARGS>
+$Ticket => undef
+$depth => 1
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowMessageHeaders b/rt/share/html/Ticket/Elements/ShowMessageHeaders
new file mode 100755
index 0000000..e77e8e2
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowMessageHeaders
@@ -0,0 +1,91 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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);
+}
+
+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
new file mode 100755
index 0000000..0d4fe61
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowMessageStanza
@@ -0,0 +1,110 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+if ( ref $Message ) {
+ $m->out('<pre>') if $plain_text_pre && !$Depth && !$plain_text_mono;
+ $m->out( qq{<div class="message-stanza-depth-$Depth">} );
+
+ my @stack;
+ my $para = '';
+ my $i = 0;
+
+ AGAIN: foreach ( ; $i < @$Message; $i++ ) {
+ my $stanza = $Message->[$i];
+ if ( ref $stanza eq "HASH" ) {
+ $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);
+ $m->out( qq{<div class="message-stanza-depth-$Depth">} );
+ }
+ if ( length $para ) {
+ $print_content->( \$para ); $para = '';
+ }
+
+ if ( @stack ) {
+ ($Message, $i) = @{ pop @stack };
+ $Depth--;
+ $m->out('</div>');
+ goto AGAIN;
+ }
+
+ $m->out('</div>');
+ $m->out('</pre>') if $plain_text_pre && !$Depth && !$plain_text_mono;
+} else {
+ $print_content->( \$Message );
+}
+</%perl>
+<%INIT>
+my $plain_text_pre = RT->Config->Get('PlainTextPre', $session{'CurrentUser'});
+my $plain_text_mono = RT->Config->Get('PlainTextMono', $session{'CurrentUser'});
+
+my $ticket = $Transaction ? $Transaction->TicketObj : undef;
+
+my $print_content = sub {
+ my $ref = shift;
+ return unless defined $$ref && length $$ref;
+
+ $m->callback( content => $ref, %ARGS );
+ $m->comp('/Elements/MakeClicky', content => $ref, ticket => $ticket, %ARGS);
+ unless ( $plain_text_pre || $plain_text_mono ) {
+ $$ref =~ s{(\r?\n)}{<br />}g if defined $$ref;
+ }
+ $m->out( $$ref );
+};
+</%INIT>
+<%ARGS>
+$Message => undef
+$Depth => 0
+$Transaction => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowParents b/rt/share/html/Ticket/Elements/ShowParents
new file mode 100644
index 0000000..38c427f
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowParents
@@ -0,0 +1,63 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<ul>
+% while (my $link = $member_of->Next) {
+<li><& /Elements/ShowLink, URI => $link->TargetURI &><br />
+% }
+</ul>
+<%INIT>
+
+return unless $Ticket;
+my $member_of = $Ticket->MemberOf;
+return unless $member_of->Count;
+
+</%INIT>
+
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowPeople b/rt/share/html/Ticket/Elements/ShowPeople
new file mode 100755
index 0000000..ddd2e3c
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowPeople
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+ <tr>
+ <td class="label"><&|/l&>Owner</&>:</td>
+% my $owner = $Ticket->OwnerObj;
+ <td class="value"><& /Elements/ShowUser, User => $owner, Ticket => $Ticket &>
+ <& /Elements/ShowUserEmailFrequency, User => $owner, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Requestors</&>:</td>
+ <td class="value"><& ShowGroupMembers, Group => $Ticket->Requestors, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Cc</&>:</td>
+ <td class="value"><& ShowGroupMembers, Group => $Ticket->Cc, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>AdminCc</&>:</td>
+ <td class="value"><& ShowGroupMembers, Group => $Ticket->AdminCc, Ticket => $Ticket &></td>
+ </tr>
+</table>
+<%INIT>
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowPriority b/rt/share/html/Ticket/Elements/ShowPriority
new file mode 100644
index 0000000..705bbae
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowPriority
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<% $Ticket->Priority %>/<% $Ticket->FinalPriority || ''%>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowQueue b/rt/share/html/Ticket/Elements/ShowQueue
new file mode 100644
index 0000000..270a825
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowQueue
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<% $QueueObj->Name %>
+<%ARGS>
+$QueueObj
+</%ARGS>
+<%INIT>
+my $value = $QueueObj->Name;
+$value = '#'. $QueueObj->id
+ unless defined $value && length $value;
+</%INIT>
diff --git a/rt/share/html/Ticket/Elements/ShowRequestor b/rt/share/html/Ticket/Elements/ShowRequestor
new file mode 100755
index 0000000..5a7ffc2
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowRequestor
@@ -0,0 +1,105 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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>
+# Unsure sane default
+unless ( @$conditions ) {
+ foreach (RT::Queue->ActiveStatusArray()) {
+ push @$conditions, { cond => "Status = '$_'", name => loc($_) };
+ }
+}
+my $rows = 10;
+my $has_right_adminusers = $session{'CurrentUser'}->HasRight(
+ Object => $RT::System, Right => 'AdminUsers'
+);
+$has_right_adminusers &&= $session{'CurrentUser'}->HasRight(
+ Object => $RT::System, Right => 'ShowConfigTab'
+);
+my $people = $Ticket->Requestors->UserMembersObj;
+while ( my $requestor = $people->Next ) {
+ next if $requestor->Privileged;
+ my $name = $m->scomp('/Elements/ShowUser', User => $requestor);
+
+ my $tickets = RT::Tickets->new( $session{'CurrentUser'} );
+ $tickets->FromSQL( "Requestor.id = ". $requestor->id ." AND (".join( " OR ", map $_->{cond}, @$conditions).")" );
+ $tickets->RowsPerPage( $rows );
+ $tickets->OrderBy( FIELD => 'Priority', ORDER => 'DESC' );
+</%PERL>
+
+<&| /Widgets/TitleBox,
+ title_href => $has_right_adminusers? RT->Config->Get('WebPath')."/Admin/Users/Modify.html?id=".$requestor->id: undef,
+ title_raw => loc("More about [_1]", $name),
+ class => 'ticket-info-requestor'
+&>
+
+%# Additional information about this user. Empty by default.
+% $m->callback( requestor => $requestor, %ARGS, CallbackName => 'AboutThisUser' );
+
+<span class="label"><&|/l&>Comments about this user</&>:</span><br />
+<b class="value"><% ($requestor->Comments || loc("No comment entered about this user")) %></b><br />
+
+<span class="label"><&|/l, $rows &>This user's [_1] highest priority tickets</&>:</span>
+<ul>
+%while (my $w=$tickets->Next) {
+%my $uri = RT::URI->new( $session{'CurrentUser'} );
+%$uri->FromObject($w);
+<li class="value"><& /Elements/ShowLink, URI => $uri &></li>
+%}
+</ul>
+
+<&|/l&>Groups this user belongs to</&>:<br />
+
+<& /Elements/ShowMemberships, UserObj => $requestor &>
+
+</&>
+
+% }
+<%ARGS>
+$Ticket=>undef
+$DisplayPath => "/Ticket/Display.html"
+$conditions => []
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/ShowSummary b/rt/share/html/Ticket/Elements/ShowSummary
new file mode 100755
index 0000000..4c2d54e
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowSummary
@@ -0,0 +1,117 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 width="100%" class="ticket-summary">
+ <tr>
+ <td valign="top" class="boxcontainer">
+ <&| /Widgets/TitleBox, title => loc('The Basics'),
+ title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id,
+ class => 'ticket-info-basics' &>
+ <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+ </&>
+
+% if ($Ticket->CustomFields->First) {
+ <&| /Widgets/TitleBox, title => loc('Custom Fields'),
+ title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id,
+ class => 'ticket-info-cfs' &>
+ <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &>
+ </&>
+% }
+ <&| /Widgets/TitleBox, title => loc('People'),
+ title_href => RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$Ticket->Id,
+ class => 'ticket-info-people' &>
+ <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
+ </&>
+
+ <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &>
+
+ <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &>
+
+% $m->callback( %ARGS, CallbackName => 'LeftColumn' );
+ </td>
+ <td valign="top" class="boxcontainer">
+% if ( RT->Config->Get('EnableReminders') ) {
+ <&|/Widgets/TitleBox, title => loc("Reminders"),
+ title_href => RT->Config->Get('WebPath')."/Ticket/Reminders.html?id=".$Ticket->Id,
+ class => 'ticket-info-reminders' &>
+ <table>
+ <tr>
+ <td>
+ <form action="<%RT->Config->Get('WebPath')%>/Ticket/Display.html" method="post">
+ <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 0 &>
+ <div align="right"><input type="submit" class="button" value="<&|/l&>Save</&>" /></div>
+ </form>
+ </td>
+ </tr>
+ </table>
+ </&>
+% }
+ <&| /Widgets/TitleBox, title => loc("Dates"),
+ title_href => RT->Config->Get('WebPath')."/Ticket/ModifyDates.html?id=".$Ticket->Id,
+ class => 'ticket-info-dates' &>
+ <& /Ticket/Elements/ShowDates, Ticket => $Ticket &>
+ </&>
+% my (@extra);
+% push @extra, titleright_raw => '<a href="'. RT->Config->Get('WebPath'). '/Ticket/Graphs/index.html?id='.$Ticket->id.'">'.loc('Graph').'</a>' unless RT->Config->Get('DisableGraphViz');
+ <&| /Widgets/TitleBox, title => loc('Links'),
+ title_href => RT->Config->Get('WebPath')."/Ticket/ModifyLinks.html?id=".$Ticket->Id,
+ class => 'ticket-info-links', @extra &>
+ <& /Elements/ShowLinks, Ticket => $Ticket &>
+ </&>
+% $m->callback( %ARGS, CallbackName => 'RightColumn' );
+
+ </td>
+ </tr>
+ </table>
+<%ARGS>
+$Ticket => undef
+$Attachments => undef
+</%ARGS>
+
+
+
+
diff --git a/rt/share/html/Ticket/Elements/ShowTime b/rt/share/html/Ticket/Elements/ShowTime
new file mode 100644
index 0000000..b4050fb
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowTime
@@ -0,0 +1,59 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 ($minutes < 60) {
+<&|/l, $minutes &>[_1] min</&>
+% } else {
+<&|/l, sprintf("%.1f",$minutes / 60) &>[quant,_1,hour]</&> (<&|/l, $minutes &>[_1] min</&>)
+% }
+<%init>
+$minutes ||= 0;
+</%init>
+<%ARGS>
+$minutes
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/Elements/ShowTransaction b/rt/share/html/Ticket/Elements/ShowTransaction
new file mode 100755
index 0000000..a533323
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowTransaction
@@ -0,0 +1,216 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 %> <% $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>
+ <span class="date"><% $transdate|n %></span>
+% my $desc = $Transaction->BriefDescription;
+% $m->callback( text => \$desc, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyDisplay' );
+ <span class="description">
+ <& /Elements/ShowUser, User => $Transaction->CreatorObj &> - <% $TicketString %> <% $desc %>
+ </span>
+% $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 ( $Transaction->CustomFieldValues->Count ) {
+ <& /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 = (
+ Create => 'message',
+ 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 };
+
+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';
+ }
+}
+
+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 = '';
+
+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\">"
+ . loc('Reply')
+ . "</a>]&nbsp;";
+ }
+ if ( $can_modify || $ticket->CurrentUserHasRight('CommentOnTicket') ) {
+ $titlebar_commands .=
+ "[<a href=\"".$UpdatePath."?id="
+ . $Transaction->Ticket
+ . "&QuoteTransaction="
+ . $Transaction->Id
+ . "&Action=Comment\">"
+ . loc('Comment') . "</a>]";
+ }
+ if ( $ticket->CurrentUserHasRight('ForwardMessage') ) {
+ $titlebar_commands .=
+ "[<a href=\"". $ForwardPath
+ . "?id=". $Transaction->Ticket
+ . "&QuoteTransaction=". $Transaction->Id
+ . "\">". 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
+ . "\">". loc('Encrypt/Decrypt') . "</a>]";
+ }
+ }
+}
+</%INIT>
diff --git a/rt/share/html/Ticket/Elements/ShowTransactionAttachments b/rt/share/html/Ticket/Elements/ShowTransactionAttachments
new file mode 100644
index 0000000..9c40b28
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowTransactionAttachments
@@ -0,0 +1,252 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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;
+ if ( $size ) {
+</%PERL>
+<div class="downloadattachment">
+<a href="<% $AttachPath %>/<% $Transaction->Id %>/<% $message->Id %>/<% ($message->Filename ||'')| u%>"><&|/l&>Download</&> <% $message->Filename || loc('(untitled)') %></a>
+% if ( $DownloadableHeaders && !$message->Filename && $message->ContentType =~ /text/ ) {
+ / <a href="<% $AttachPath %>/WithHeaders/<% $message->Id %>"><% loc('with headers') %></a>
+% }
+<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 <% RT->Config->Get('PlainTextMono', $session{'CurrentUser'}) ? ' plain-text-white-space' : ''%>">
+% }
+<%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');
+}
+
+my $size_to_str = sub {
+ my $size = shift;
+ # show a download link
+ if ( $size > 1024*1024 ) {
+ $size = loc( "[_1]b", 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;
+
+ # if it has a content-disposition: attachment, don't show inline
+ my $disposition = $message->GetHeader('Content-Disposition');
+ if ( $disposition && $disposition =~ /attachment/i && $disposition !~ /^\s*inline/ ) {
+ $disposition = 'attachemnt';
+ } else {
+ $disposition = 'inline';
+ }
+
+ # If it's text
+ if ( $message->ContentType =~ m{^(text|message)}i ) {
+ my $max_size = RT->Config->Get( 'MaxInlineBody', $session{'CurrentUser'} );
+ if ( $message->Filename && RT->Config->Get('SuppressInlineTextFiles', $session{'CurrentUser'} ) ) {
+ $m->out('<p>'. loc( 'Text file is not shown because it is disabled in preferences.' ) .'</p>');
+ return;
+ }
+ elsif ( $max_size && $message->ContentLength > $max_size ) {
+ $m->out('<p>'. loc( 'Message body not shown because it is too large.' ) .'</p>');
+ return;
+ }
+ elsif ( $disposition ne 'inline' ) {
+ $m->out('<p>'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'</p>');
+ return;
+ }
+
+ if (
+
+ # it's a toplevel object
+ !$ParentObj
+
+ # or its parent isn't a multipart alternative
+ || ( $ParentObj->ContentType !~ m{^multipart/alternative$}i )
+
+ # or it's of our prefered alterative type
+ || (
+ (
+ RT->Config->Get('PreferRichText')
+ && ( $message->ContentType =~ m{^text/(?:html|enriched)$} )
+ )
+ || ( !RT->Config->Get('PreferRichText')
+ && ( $message->ContentType !~ m{^text/(?:html|enriched)$} )
+ )
+ )
+ )
+ {
+
+ my $content;
+ if ( $AttachmentContent->{ $message->id } ) {
+ $content = $AttachmentContent->{ $message->id }->Content;
+ }
+ else {
+ $content = $message->Content;
+ }
+
+ # if it's a text/html clean the body and show it
+ if ( $message->ContentType =~ m{^text/(?:html|enriched)$}i ) {
+ $content = $m->comp( '/Elements/ScrubHTML', Content => $content );
+ if ( $message->ContentType eq 'text/html' ) {
+ $m->comp('/Elements/MakeClicky',
+ content => \$content, html => 1,
+ ticket => $Ticket );
+ }
+ $m->out( $content );
+ }
+
+ # if it's a text/plain show the body
+ elsif ( $message->ContentType =~ m{^(text|message)}i ) {
+
+ eval { require Text::Quoted; $content = Text::Quoted::extract($content); };
+ if ($@) { $RT::Logger->warning( "Text::Quoted failed: $@" ) }
+
+ $m->comp(
+ 'ShowMessageStanza',
+ Depth => 0,
+ Message => $content,
+ Transaction => $Transaction
+ );
+ }
+ }
+ }
+
+ # if it's an image, show it as an image
+ elsif ( RT->Config->Get('ShowTransactionImages') and $message->ContentType =~ /^image\//i ) {
+ if ( $disposition ne 'inline' ) {
+ $m->out('<p>'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'</p>');
+ return;
+ }
+
+ my $filename = $message->Filename || loc('(untitled)');
+ $m->out('<img'
+ . ' alt="'
+ . $filename
+ . '"'
+ . ' title="'
+ . $filename
+ . '"'
+ . ' src="'
+ . $AttachPath . '/'
+ . $Transaction->Id . '/'
+ . $message->Id
+ . '/" />' );
+ }
+ elsif ( $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/ShowUpdateStatus b/rt/share/html/Ticket/Elements/ShowUpdateStatus
new file mode 100644
index 0000000..4eb53b4
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowUpdateStatus
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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="unread-messages">
+<&| /Widgets/TitleBox, title => loc('New messages'), title_href => "#txn-". $txn->id &>
+<&|/l, &>There are unread messages on this ticket.</&>
+<&|/l,
+ RT->Config->Get('WebPath') ."/Ticket/Display.html?id=". $Ticket->id. "#txn-".$txn->id,
+ RT->Config->Get('WebPath') ."/Ticket/Display.html?id=". $Ticket->id ."&MarkAsSeen=1". "#txn-".$txn->id
+
+ &>You can <a href="[_1]">jump to the first unread message</a> or <a href="[_2]">jump to the first unread message and mark all messages as seen</a>.</&>
+</&>
+</div>
+<%ARGS>
+$Ticket
+</%ARGS>
+<%INIT>
+return unless (RT->Config->Get( 'ShowUnreadMessageNotifications', $session{'CurrentUser'}));
+my $txn = $Ticket->SeenUpTo or return;
+</%INIT>
diff --git a/rt/share/html/Ticket/Elements/ShowUserEntry b/rt/share/html/Ticket/Elements/ShowUserEntry
new file mode 100644
index 0000000..5e4a463
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/ShowUserEntry
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/ShowUser, %ARGS &>
+% if ($Ticket and grep { $_->Content eq $User->EmailAddress } $Ticket->SquelchMailTo) {
+<b><&|/l&>(Will not be sent email)</&></b>
+% }
+
+<%ARGS>
+$User => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/Tabs b/rt/share/html/Ticket/Elements/Tabs
new file mode 100755
index 0000000..7deb8c1
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/Tabs
@@ -0,0 +1,341 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+% $m->callback( Ticket => $Ticket, actions=> $actions, tabs => $tabs, %ARGS );
+<& /Elements/Tabs,
+ tabs => $tabs,
+ actions => $actions,
+ current_tab => $current_tab,
+ current_toptab => $current_toptab,
+ Title => $Title &>
+<%INIT>
+my $tabs = {};
+my $current_toptab = "Search/Build.html", my $searchtabs = {};
+my $actions;
+
+if ($Ticket) {
+
+ my $id = $Ticket->id();
+
+ if ( defined $session{'tickets'} ) {
+
+ # we have to update session data if we get new ItemMap
+ my $updatesession = 1 unless ( $session{'tickets'}->{'item_map'} );
+
+ my $item_map = $session{'tickets'}->ItemMap;
+
+ if ($updatesession) {
+ $session{'i'}++;
+ $session{'tickets'}->PrepForSerialization();
+ }
+
+ # Don't display prev links if we're on the first ticket
+ if ( $item_map->{ $Ticket->Id }->{prev} ) {
+ $searchtabs->{'_a'} = {
+ class => "nav",
+ path => "Ticket/Display.html?id=" . $item_map->{first},
+ title => '<< ' . loc('First')
+ };
+ $searchtabs->{"_b"} = {
+ class => "nav",
+ path => "Ticket/Display.html?id="
+ . $item_map->{ $Ticket->Id }->{prev},
+ title => '< ' . loc('Prev')
+ };
+ }
+
+ # Don't display next links if we're on the last ticket
+ if ( $item_map->{ $Ticket->Id }->{next} ) {
+ $searchtabs->{'d'} = {
+ class => "nav",
+ path => "Ticket/Display.html?id="
+ . $item_map->{ $Ticket->Id }->{next},
+ title => loc('Next') . ' >'
+ };
+ $searchtabs->{'e'} = {
+ class => "nav",
+ path => "Ticket/Display.html?id=" . $item_map->{last},
+ title => loc('Last') . ' >>'
+ };
+ }
+ }
+
+ $tabs->{"this"} = {
+ class => "currentnav",
+ path => "Ticket/Display.html?id=" . $Ticket->id,
+ title => "#" . $id,
+ current_subtab => $current_subtab
+ };
+
+ my $ticket_page_tabs = {
+ _A => {
+ title => loc('Display'),
+ path => "Ticket/Display.html?id=" . $id,
+ },
+
+ _Ab => {
+ title => loc('History'),
+ path => "Ticket/History.html?id=" . $id,
+ },
+ _B => {
+ title => loc('Basics'),
+ path => "Ticket/Modify.html?id=" . $id,
+ },
+
+ _C => {
+ title => loc('Dates'),
+ path => "Ticket/ModifyDates.html?id=" . $id,
+ },
+ _D => {
+ title => loc('People'),
+ path => "Ticket/ModifyPeople.html?id=" . $id,
+ },
+ _E => {
+ title => loc('Links'),
+ path => "Ticket/ModifyLinks.html?id=" . $id,
+ },
+ _X => {
+ title => loc('Jumbo'),
+ path => "Ticket/ModifyAll.html?id=" . $id,
+ },
+
+ };
+
+ if ( RT->Config->Get('EnableReminders') ) {
+ $ticket_page_tabs->{_F} = {
+ title => loc('Reminders'),
+ path => "Ticket/Reminders.html?id=" . $id,
+ separator => 1,
+ };
+ }
+
+ foreach my $tab ( sort keys %{$ticket_page_tabs} ) {
+ if ( $ticket_page_tabs->{$tab}->{'path'} eq $current_tab ) {
+ $ticket_page_tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{'this'}->{"current_subtab"}
+ = $ticket_page_tabs->{$tab}->{"path"};
+ }
+ }
+ $tabs->{'this'}->{"subtabs"} = $ticket_page_tabs;
+ $current_tab = "Ticket/Display.html?id=" . $id;
+
+ my %can = ( ModifyTicket => $Ticket->CurrentUserHasRight('ModifyTicket'), );
+
+ if ( $can{'ModifyTicket'} or $Ticket->CurrentUserHasRight('ReplyToTicket') )
+ {
+ $actions->{'F'} = {
+ title => loc('Reply'),
+ path => "Ticket/Update.html?Action=Respond&id=" . $id,
+ };
+ }
+
+ if ( $Ticket->CurrentUserHasRight('ForwardMessage') )
+ {
+ $actions->{'FA'} = {
+ title => loc('Forward'),
+ path => "Ticket/Forward.html?id=" . $id,
+ };
+ }
+
+ if ( $can{'ModifyTicket'} ) {
+ if ( $Ticket->Status ne 'resolved' ) {
+ $actions->{'G'} = {
+ path =>
+ "Ticket/Update.html?Action=Comment&DefaultStatus=resolved&id="
+ . $id,
+ title => loc('Resolve')
+ };
+ }
+ if ( $Ticket->Status ne 'open' ) {
+ $actions->{'A'} = {
+ path => "Ticket/Display.html?Status=open&id=" . $id,
+ title => loc('Open it')
+ };
+ }
+ }
+
+ if ( $Ticket->CurrentUserHasRight('OwnTicket') ) {
+ if ( $Ticket->OwnerObj->Id == $RT::Nobody->id ) {
+ $actions->{'B'} = {
+ path => "Ticket/Display.html?Action=Take&id=" . $id,
+ title => loc('Take'),
+ }
+ if $can{'ModifyTicket'}
+ or $Ticket->CurrentUserHasRight('TakeTicket');
+ } elsif ( $Ticket->OwnerObj->id != $session{CurrentUser}->id ) {
+ $actions->{'C'} = {
+ path => "Ticket/Display.html?Action=Steal&id=" . $id,
+ title => loc('Steal'),
+ }
+ if $can{'ModifyTicket'}
+ or $Ticket->CurrentUserHasRight('StealTicket');
+ }
+ }
+
+ if ( $can{'ModifyTicket'}
+ or $Ticket->CurrentUserHasRight('CommentOnTicket') )
+ {
+ $actions->{'E'} = {
+ title => loc('Comment'),
+ path => "Ticket/Update.html?Action=Comment&id=" . $id,
+ };
+ }
+
+ $actions->{'_ZZ'}
+ = { html => $m->scomp( '/Ticket/Elements/Bookmark', id => $Ticket->id ),
+ };
+
+}
+
+if ( ( defined $actions->{A} || defined $actions->{B} || defined $actions->{C} )
+ && ( defined $actions->{E}
+ || defined $actions->{F}
+ || defined $actions->{G} ) )
+{
+
+ if ( defined $actions->{C} ) { $actions->{C}->{separator} = 1 }
+ elsif ( defined $actions->{B} ) { $actions->{B}->{separator} = 1 }
+ elsif ( defined $actions->{A} ) { $actions->{A}->{separator} = 1 }
+}
+
+my $args = '';
+my $has_query = '';
+my %query_args;
+my $search_id = $ARGS{'SavedSearchId'}
+ || $session{'CurrentSearchHash'}->{'SearchId'} || '';
+my $chart_search_id = $ARGS{'SavedChartSearchId'} || '';
+
+$has_query = 1 if ( $ARGS{'Query'} or $session{'CurrentSearchHash'}->{'Query'} );
+
+%query_args = (
+ SavedSearchId => ($search_id eq 'new') ? undef : $search_id,
+ SavedChartSearchId => $chart_search_id,
+ Query => $ARGS{'Query'} || $session{'CurrentSearchHash'}->{'Query'},
+ Format => $ARGS{'Format'} || $session{'CurrentSearchHash'}->{'Format'},
+ OrderBy => $ARGS{'OrderBy'}
+ || $session{'CurrentSearchHash'}->{'OrderBy'},
+ Order => $ARGS{'Order'} || $session{'CurrentSearchHash'}->{'Order'},
+ Page => $ARGS{'Page'} || $session{'CurrentSearchHash'}->{'Page'},
+ RowsPerPage => $ARGS{'RowsPerPage'} || $session{'CurrentSearchHash'}->{'RowsPerPage'},
+ );
+
+ $args = "?" . $m->comp( '/Elements/QueryString', %query_args );
+
+$tabs->{"f"} = {
+ path => "Search/Build.html?NewQuery=1",
+ title => loc('New Search')
+};
+$tabs->{"g"} = {
+ path => "Search/Build.html" . (($has_query) ? $args : ''),
+ title => loc('Edit Search')
+};
+$tabs->{"h"} = {
+ path => "Search/Edit.html$args",
+ title => loc('Advanced'),
+ separator => 1
+};
+if ($has_query) {
+
+ if ( $current_tab =~ m{Search/Results.html} ) {
+ $current_tab = "Search/Results.html$args";
+
+ if ( $session{'CurrentUser'}
+ ->HasRight( Right => 'SuperUser', Object => $RT::System ) )
+ {
+ my $shred_args = $m->comp(
+ '/Elements/QueryString',
+ Search => 1,
+ Plugin => 'Tickets',
+ 'Tickets:query' => $query_args{'Query'},
+ 'Tickets:limit' => $query_args{'Rows'}
+ );
+
+ $tabs->{"shredder"} = {
+ path => 'Admin/Tools/Shredder/?' . $shred_args,
+ title => loc('Shredder')
+ };
+
+ }
+ }
+ if ( $current_tab =~ m{Search/(Bulk|Build|Edit)\.html} ) {
+ $current_tab = "Search/$1.html$args";
+ }
+
+ $tabs->{"i"} = {
+ path => "Search/Results.html$args",
+ title => loc('Show Results'),
+ };
+
+ $tabs->{"j"} = {
+ path => "Search/Bulk.html$args",
+ title => loc('Bulk Update'),
+ };
+
+ $tabs->{"k"} = {
+ path => "Search/Chart.html$args",
+ title => loc('Graph'),
+ };
+
+}
+
+foreach my $searchtab ( keys %{$searchtabs} ) {
+ ( $searchtab =~ /^_/ )
+ ? $tabs->{ "s" . $searchtab } = $searchtabs->{$searchtab}
+ : $tabs->{ "z_" . $searchtab } = $searchtabs->{$searchtab};
+}
+
+</%INIT>
+
+
+<%ARGS>
+$Ticket => undef
+$subtabs => undef
+$current_tab => ''
+$current_subtab => ''
+$Title => undef
+$RowsPerPage => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/Elements/UpdateCc b/rt/share/html/Ticket/Elements/UpdateCc
new file mode 100644
index 0000000..2538c82
--- /dev/null
+++ b/rt/share/html/Ticket/Elements/UpdateCc
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<tr><td class="label"><&|/l&>One-time Cc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateCc', Size => '60', Default => $ARGS{UpdateCc} &>
+<input type="hidden" id="UpdateIgnoreAddressCheckboxes" name="UpdateIgnoreAddressCheckboxes" value="0">
+ <br />
+
+%foreach my $addr ( keys %txn_addresses) {
+% next if ( grep {$addr eq $_} @req_addresses );
+<input
+id="UpdateCc-<%$addr%>"
+name="UpdateCc-<%$addr%>"
+ type="checkbox"
+ onClick="checkboxToInput('UpdateCc', 'UpdateCc-<%$addr%>','<%$txn_addresses{$addr}->format%>' ); $(UpdateIgnoreAddressCheckboxes).value=1"
+ <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> > <& /Elements/ShowUser, Address => $txn_addresses{$addr}&>
+%}
+</td></tr>
+<tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => '60', Default => $ARGS{UpdateBcc} &><br />
+%foreach my $addr ( keys %txn_addresses) {
+% next if ( grep {$addr eq $_} @req_addresses );
+<input
+ id="UpdateBcc-<%$addr%>"
+ name="UpdateBcc-<%$addr%>"
+ type="checkbox"
+ onClick="checkboxToInput('UpdateBcc', 'UpdateBcc-<%$addr%>','<%$txn_addresses{$addr}->format%>' ); $(UpdateIgnoreAddressCheckboxes).value=1"
+ <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%>>
+<& /Elements/ShowUser, Address => $txn_addresses{$addr}&>
+%}
+</td></tr>
+<%args>
+$TicketObj
+</%args>
+<%init>
+my %txn_addresses = %{$TicketObj->TransactionAddresses};
+my @req_addresses = split /,/, $TicketObj->RequestorAddresses;
+</%init>
diff --git a/rt/share/html/Ticket/Forward.html b/rt/share/html/Ticket/Forward.html
new file mode 100644
index 0000000..9830f91
--- /dev/null
+++ b/rt/share/html/Ticket/Forward.html
@@ -0,0 +1,123 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => $Title &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ Title => $Title,
+&>
+
+% $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj);
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="Forward.html" name="ForwardMessage" method="post">
+% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS );
+<input type="hidden" class="hidden" name="id" value="<% $id %>" /><br />
+<input type="hidden" class="hidden" name="QuoteTransaction" value="<% $ARGS{'QuoteTransaction'} %>" />
+
+<table border="0">
+
+<tr><td align="right"><&|/l&>Subject</&>:</td>
+<td><% $TicketObj->Subject %></td></tr>
+
+<tr><td align="right"><&|/l&>To</&>:</td>
+<td><input name="To" size="60" value="<% $ARGS{'To'} %>" /></td></tr>
+
+<tr><td align="right"><&|/l&>Cc</&>:</td>
+<td><input name="Cc" size="60" value="<% $ARGS{'Cc'} %>" /></td></tr>
+
+<tr><td align="right"><&|/l&>BCc</&>:</td>
+<td><input name="Bcc" size="60" value="<% $ARGS{'Bcc'} %>" /></td></tr>
+
+</table>
+
+<& /Elements/Submit, Label => loc('Forward Message and Return'), Name => 'ForwardAndReturn' &>
+<& /Elements/Submit, Label => loc('Forward Message'), Name => 'Forward' &>
+</form>
+<%INIT>
+my $TicketObj = LoadTicket($id);
+$id = $ARGS{'id'} = $TicketObj->id;
+
+Abort( loc("Permission Denied") )
+ unless $TicketObj->CurrentUserHasRight('ForwardMessage');
+
+my $txn;
+if ( $QuoteTransaction ) {
+ $txn = RT::Transaction->new( $session{'CurrentUser'} );
+ $txn->Load( $QuoteTransaction );
+ Abort( loc("Couldn't load transaction #[_1]", $QuoteTransaction) )
+ unless $txn->id;
+}
+
+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 );
+ push @results, $msg;
+
+ if ( $ForwardAndReturn ) {
+ $session{'i'}++;
+ my $key = Digest::MD5::md5_hex(rand(1024));
+ push @{ $session{"Actions"}->{$key} ||= [] }, @results;
+ RT::Interface::Web::Redirect( RT->Config->Get('WebURL') ."Ticket/Display.html?id=". $id."&results=".$key);
+ }
+}
+
+my $Title = $txn
+ ? loc('Forward transaction #[_1]', $txn->id)
+ : loc('Forward ticket #[_1]', $TicketObj->id);
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+$QuoteTransaction => undef
+$ForwardAndReturn => 0,
+$Forward => $ForwardAndReturn,
+</%ARGS>
diff --git a/rt/share/html/Ticket/GnuPG.html b/rt/share/html/Ticket/GnuPG.html
new file mode 100644
index 0000000..243da6a
--- /dev/null
+++ b/rt/share/html/Ticket/GnuPG.html
@@ -0,0 +1,104 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $txn->TicketObj,
+ current_tab => 'Ticket/Encrypt.html?id='. $id,
+ Title => $title,
+&>
+
+% $m->callback( CallbackName => 'BeforeActionList', %ARGS, Actions => \@results, ARGSRef => \%ARGS );
+<& /Elements/ListActions, actions => \@results &>
+<form method="post" action="<% RT->Config->Get('WebPath') . $m->request_comp->path %>?id=<% $id %>">
+<a href="<% RT->Config->Get('WebURL') %>Ticket/Display.html?id=<% $txn->Ticket %>#txn-<% $id %>">
+<% loc('Return back to the ticket') %>
+</a>
+<& /Elements/Submit,
+ Label => ($encrypted? loc('Decrypt'): loc('Encrypt')),
+ Name => ($encrypted? 'Decrypt': 'Encrypt'),
+&>
+</form>
+<%ARGS>
+$id => undef
+$Encrypt => 0
+$Decrypt => 0
+</%ARGS>
+<%INIT>
+my $txn = RT::Transaction->new( $session{'CurrentUser'} );
+$txn->Load( $id );
+unless ( $txn->id ) {
+ Abort(loc("Couldn't load transaction #[_1]", $id));
+}
+$id = $txn->id;
+
+my @results;
+
+my $encrypted = 0;
+
+my $attachments = $txn->Attachments;
+while ( my $attachment = $attachments->Next ) {
+ next unless $attachment->ContentType =~ m{^x-application-rt/gpg-encrypted\b};
+ $encrypted = 1;
+ last;
+}
+$attachments->GotoFirstItem;
+
+if ( $Encrypt || $Decrypt ) {
+ my $done = 1;
+ while ( my $attachment = $attachments->Next ) {
+ my ($status, $msg) = $Decrypt? $attachment->Decrypt : $attachment->Encrypt;
+ push @results, $msg;
+ unless ( $status ) {
+ $done = 0; last;
+ }
+ }
+ $encrypted = !$encrypted if $done;
+}
+
+my $title = loc("Encrypt/Decrypt transaction #[_1] of ticket #[_2]", $id, $txn->Ticket);
+</%INIT>
diff --git a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties
new file mode 100644
index 0000000..76d28ee
--- /dev/null
+++ b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties
@@ -0,0 +1,167 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<&| /Widgets/TitleBox, title => loc('Graph Properties') &>
+
+<% loc('Direction') %> <select name="Direction">
+<option value="TB" <% ($Direction||'TB') eq 'TB'? 'selected="selected"': '' |n %>><% loc('top to bottom') %></option>
+<option value="LR" <% ($Direction||'TB') eq 'LR'? 'selected="selected"': '' |n %>><% loc('left to right') %></option>
+%# XXX: not supported by GraphViz perl module
+%#<option value="BT" <% ($Direction||'TB') eq 'BT'? 'selected="selected"': '' |n %>><% loc('bottom to top') %></option>
+%#<option value="RL" <% ($Direction||'TB') eq 'RL'? 'selected="selected"': '' |n %>><% loc('right to left') %></option>
+</select><br />
+
+<% loc('Main type of links') %> <select name="LeadingLink">
+% foreach ( @link_types ) {
+<option value="<% $_ %>" <% ($LeadingLink||'Members') eq $_? 'selected="selected"': '' |n %>><% loc($_) %></option>
+% }
+</select>
+
+<% loc('maximum depth') %> <select name="MaxDepth">
+<option value="0"><% loc('Unlimit') %></option>
+% foreach ( 1..6 ) {
+<option value="<% $_ %>" <% ($MaxDepth||0) == $_? 'selected="selected"': '' %>><% $_ %></option>
+% }
+</select><br />
+
+<% loc('Show as well') %>:
+% 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) %>
+% }
+<br />
+
+% my @properties = RT::Graph::Tickets->TicketProperties( $session{'CurrentUser'} );
+
+<% loc('Fill boxes with color using') %>:
+<select name="FillUsing">
+<option value=""><% loc('nothing') %></option>
+<%PERL>
+my @tmp = @properties;
+while ( my ($group, $list) = (splice @tmp, 0, 2) ) {
+ # coloring by links and dates sounds stupid
+ next if $group eq 'Dates' || $group eq 'Links';
+
+ foreach my $prop ( @$list ) {
+ my $selected = '';
+ $selected = 'selected="selected"' if $prop eq ($FillUsing||'');
+</%PERL>
+<option value="<% $prop %>" <% $selected |n %>><% loc($prop) %></option>
+% } }
+</select><br />
+
+% 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 %> />
+<br />
+% }
+
+<%PERL>
+for my $i ( 1..($MaxDepth||6) ) {
+ my @default;
+ if ( my $tmp = $ARGS{ 'Level-'. $i .'-Properties' } ) {
+ @default = ref $tmp? @$tmp : ($tmp);
+ }
+
+ $m->comp('SELF:Properties',
+ Level => $i,
+ Available => \@properties,
+ Default => \@default,
+ );
+}
+</%PERL>
+
+<& /Elements/Submit, Label => loc('Update Graph'), Name => 'Update' &>
+
+</&>
+
+<%ARGS>
+$id => undef
+$Direction => 'TB'
+$LeadingLink => 'Members'
+@ShowLinks => ('MemberOf', 'DependsOn', 'RefersTo')
+$MaxDepth => 3
+$FillUsing => ''
+$ShowLinkDescriptions => 0
+</%ARGS>
+<%INIT>
+require RT::Graph::Tickets;
+require RT::Link;
+
+my @link_types = qw(Members MemberOf RefersTo ReferredToBy DependsOn DependedOnBy); #loc_qw
+@ShowLinks = grep $_ ne $LeadingLink, @ShowLinks;
+</%INIT>
+
+<%METHOD Properties>
+<%ARGS>
+@Available => ()
+@Default => ()
+$Level => 1,
+</%ARGS>
+<%INIT>
+my $id = "graph-properties-box-$Level";
+my $class = '';
+$class = 'class="hidden"' if $Level != 1 && !@Default;
+</%INIT>
+<% loc('Show Tickets Properties on [_1] level', $Level) %>
+(<small><a href="#" onclick="hideshow('<% $id %>'); return false;"><% loc('open/close') %></a></small>):
+<table id="<% $id %>" <% $class |n %>>
+% while ( my ($group, $list) = (splice @Available, 0, 2) ) {
+<tr><td><% loc($group) %>:</td><td>
+% 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) %>
+% }
+</td></tr>
+% }
+</table>
+<br />
+</%METHOD>
diff --git a/rt/share/html/Ticket/Graphs/Elements/ShowGraph b/rt/share/html/Ticket/Graphs/Elements/ShowGraph
new file mode 100644
index 0000000..d989ecc
--- /dev/null
+++ b/rt/share/html/Ticket/Graphs/Elements/ShowGraph
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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><img src="<% RT->Config->Get('WebPath') %>/Ticket/Graphs/<% $id %>?<% $m->comp('/Elements/QueryString', %ARGS) %>" usemap="#<% $graph->{'NAME'} || 'test' %>" style="border: none" />
+<% safe_run_child { Encode::decode_utf8( $graph->as_cmapx ) } |n %>
+</div>
+<& ShowLegends, %ARGS, Ticket => $ticket &>
+<%ARGS>
+$id => undef
+</%ARGS>
+<%INIT>
+use RT::Util 'safe_run_child';
+
+my $ticket = RT::Ticket->new( $session{'CurrentUser'} );
+$ticket->Load( $id );
+unless ( $ticket->id ) {
+ $RT::Logger->error("Couldn't load ticket $id");
+ return;
+}
+$ARGS{'id'} = $id = $ticket->id;
+
+require RT::Graph::Tickets;
+my $graph = RT::Graph::Tickets->TicketLinks(
+ %ARGS,
+ Ticket => $ticket,
+);
+</%INIT>
diff --git a/rt/share/html/Ticket/Graphs/Elements/ShowLegends b/rt/share/html/Ticket/Graphs/Elements/ShowLegends
new file mode 100644
index 0000000..9a4fa14
--- /dev/null
+++ b/rt/share/html/Ticket/Graphs/Elements/ShowLegends
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<&| /Widgets/TitleBox, title => loc('Legends'), hideable => $hideable &>
+<table>
+
+<tr style="height: 2.8em;"><td><% loc('Status') %>:</td><td>
+% foreach my $status ( sort keys %RT::Graph::Tickets::ticket_status_style ) {
+% my $style = $RT::Graph::Tickets::ticket_status_style{ $status };
+<span style="color: <% $style->{'fontcolor'} %>; padding: 0.6em; border: 1px solid black;"><% loc($status) %></span>
+% }
+</td></tr>
+
+% if ( $FillUsing ) {
+<tr style="height: 2.8em;"><td><% loc($FillUsing) %>:</td><td>
+% foreach my $value ( sort keys %RT::Graph::Tickets::fill_cache ) {
+% my $color = $RT::Graph::Tickets::fill_cache{ $value };
+<span style="background-color: <% $color %>; padding: 0.6em; border: 1px solid black;"><% loc($value) %></span>
+% }
+</td></tr>
+% }
+
+</table>
+</&>
+
+<%ARGS>
+$FillUsing => ''
+$hideable => 1
+</%ARGS>
diff --git a/rt/share/html/Ticket/Graphs/dhandler b/rt/share/html/Ticket/Graphs/dhandler
new file mode 100644
index 0000000..033a534
--- /dev/null
+++ b/rt/share/html/Ticket/Graphs/dhandler
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 $arg = $m->dhandler_arg;
+
+my $id;
+if ( $arg =~ m{^(\d+)$}i ) {
+ ($id) = ($1);
+} else {
+ return $m->abort( 404 );
+}
+
+my $ticket = RT::Ticket->new($session{'CurrentUser'} );
+$ticket->Load( $id );
+unless ( $ticket->id ) {
+ $RT::Logger->error("Couldn't load ticket #$id");
+ return $m->abort( 404 );
+}
+
+require RT::Graph::Tickets;
+my $graph = RT::Graph::Tickets->TicketLinks(
+ %ARGS,
+ Ticket => $ticket,
+);
+
+$r->content_type( 'image/png' );
+$m->clear_buffer;
+
+my $png;
+safe_run_child { $graph->as_png(\$png) };
+$m->out( $png );
+
+$m->abort;
+
+</%INIT>
diff --git a/rt/share/html/Ticket/Graphs/index.html b/rt/share/html/Ticket/Graphs/index.html
new file mode 100644
index 0000000..e23737c
--- /dev/null
+++ b/rt/share/html/Ticket/Graphs/index.html
@@ -0,0 +1,114 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $ticket,
+ Title => $title,
+ current_tab => "Ticket/ModifyLinks.html?id=$id",
+&>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<& Elements/ShowGraph, %ARGS, Ticket => $ticket &>
+
+<form action="<% RT->Config->Get('WebPath') . $m->request_comp->path %>">
+<input type="hidden" class="hidden" name="id" value="<% $id %>" />
+
+<& Elements/EditGraphProperties, %ARGS, Ticket => $ticket &>
+
+<input type="hidden" class="hidden" name="SavedSearchId" value="<% $saved_search->{Id} %>" />
+<& /Search/Elements/EditSearches,
+ %$saved_search,
+ Title => loc('Manage saved graphs'),
+ Type => 'Graph',
+ SearchFields => \@save_arguments,
+ CurrentSearch => { map { $_ => $ARGS{$_} } @save_arguments },
+ AllowCopy => 0,
+&>
+</form>
+
+<%ARGS>
+</%ARGS>
+<%INIT>
+use RT::Graph::Tickets;
+my @results;
+
+my @save_arguments = qw(id Direction LeadingLink ShowLinks MaxDepth FillUsing ShowLinkDescriptions);
+foreach my $level ( 0 .. 6 ) {
+ push @save_arguments, "Level-". $level ."-Properties";
+}
+my $saved_search = { Type => 'Graph' };
+push @results, $m->comp( '/Search/Elements/EditSearches:Init',
+ %ARGS,
+ Query => \%ARGS,
+ SavedSearch => $saved_search,
+ SearchFields => \@save_arguments,
+);
+
+my $id = $ARGS{'id'};
+my $ticket = LoadTicket( $id );
+$ARGS{'id'} = $id = $ticket->id;
+
+$ARGS{'LeadingLink'} ||= 'Members';
+if ( $ARGS{'ShowLinks'} && !ref $ARGS{'ShowLinks'} ) {
+ $ARGS{'ShowLinks'} = [$ARGS{'ShowLinks'}];
+} elsif ( !$ARGS{'ShowLinks'} ) {
+ $ARGS{'ShowLinks'} = [ qw(MemberOf DependsOn RefersTo) ];
+}
+$ARGS{'ShowLinks'} = [ grep $_ ne $ARGS{'LeadingLink'}, @{ $ARGS{'ShowLinks'} } ];
+$ARGS{'MaxDepth'} = 3 unless defined $ARGS{'MaxDepth'} && length $ARGS{'MaxDepth'};
+
+push @results, $m->comp( '/Search/Elements/EditSearches:Save',
+ %ARGS,
+ Query => \%ARGS,
+ SavedSearch => $saved_search,
+ SearchFields => \@save_arguments,
+);
+
+my $title = loc( "Ticket #[_1] relationships graph", $id );
+</%INIT>
diff --git a/rt/share/html/Ticket/History.html b/rt/share/html/Ticket/History.html
new file mode 100755
index 0000000..3e9d143
--- /dev/null
+++ b/rt/share/html/Ticket/History.html
@@ -0,0 +1,91 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket, current_tab => 'Ticket/History.html?id='.$Ticket->id,
+ Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+% $m->callback( %ARGS, Ticket => $Ticket, CallbackName => 'BeforeActionList' );
+
+
+<br />
+
+<& /Ticket/Elements/ShowHistory ,
+ Ticket => $Ticket,
+ ShowHeaders => $ARGS{'ShowHeaders'},
+ URIFile => 'History.html',
+ Attachments => $attachments,
+ AttachmentContent => $attachment_content
+ &>
+
+% $m->callback( %ARGS, CallbackName => 'AfterShowHistory', Ticket => $Ticket, current_tab => 'Ticket/History.html?id=' . $Ticket->id );
+
+<%ARGS>
+$id => undef
+</%ARGS>
+
+<%INIT>
+
+
+
+my $Ticket = LoadTicket ($id);
+
+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);
+
+
+</%INIT>
+
+
+
+
diff --git a/rt/share/html/Ticket/Modify.html b/rt/share/html/Ticket/Modify.html
new file mode 100755
index 0000000..e7d370f
--- /dev/null
+++ b/rt/share/html/Ticket/Modify.html
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc('Modify ticket #[_1]', $TicketObj->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj, current_subtab => "Ticket/Modify.html?id=".$TicketObj->Id,
+ Title => loc('Modify ticket #[_1]', $TicketObj->Id) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj);
+
+<& /Elements/ListActions, actions => \@results &>
+<form method="post" action="Modify.html" enctype="multipart/form-data">
+% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS );
+<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 &>
+</&>
+
+<& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#993333" &>
+</form>
+<%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 => {},
+);
+
+# Now let callbacks have a chance at editing %ARGS
+$m->callback( TicketObj => $TicketObj, CustomFields => $CustomFields, ARGSRef => \%ARGS );
+
+my @results = ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS);
+push @results, ProcessObjectCustomFieldUpdates(Object => $TicketObj, ARGSRef => \%ARGS);
+
+$TicketObj->ApplyTransactionBatch;
+
+# TODO: display the results, even if we can't display the ticket
+unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+}
+
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/ModifyAll.html b/rt/share/html/Ticket/ModifyAll.html
new file mode 100755
index 0000000..7628700
--- /dev/null
+++ b/rt/share/html/Ticket/ModifyAll.html
@@ -0,0 +1,255 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyAll.html?id=".$Ticket->Id,
+ Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket);
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="ModifyAll.html" enctype="multipart/form-data">
+% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS );
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" />
+
+<&| /Widgets/TitleBox, title => loc('Modify ticket # [_1]', $Ticket->Id), class=>'ticket-info-basics' &>
+<& Elements/EditBasics, TicketObj => $Ticket &>
+<& Elements/EditCustomFields, TicketObj => $Ticket &>
+</&>
+
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Dates'), class=>'ticket-info-dates'&>
+<& Elements/EditDates, TicketObj => $Ticket &>
+</&>
+
+<br />
+
+
+<&| /Widgets/TitleBox, title => loc('People'), class=>'ticket-info-people' &>
+<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp, GroupString => $GroupString, GroupOp => $GroupOp, GroupField => $GroupField &>
+</&>
+
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Links'), class=>'ticket-info-links' &>
+<& /Elements/EditLinks, Object => $Ticket, Merge => 1 &>
+</&>
+
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Update ticket') &>
+<table>
+ <tr>
+ <td class="label"><&|/l&>Update Type</&>:</td>
+ <td class="entry">
+ <select name="UpdateType">
+% if ($CanComment) {
+ <option value="private" ><&|/l&>Comments (Not sent to requestors)</&></option>
+% }
+% if ($CanRespond) {
+ <option value="response"><&|/l&>Reply to requestors</&></option>
+% }
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Subject</&>:</td>
+ <td class="entry"><input name="UpdateSubject" size="60" value="<%$Ticket->Subject%>" /></td>
+ </tr>
+% if (my $TxnCFs = $Ticket->TransactionCustomFields) {
+% while (my $CF = $TxnCFs->Next()) {
+<tr>
+<td class="label"><% loc($CF->Name) %>:</td>
+<td class="entry"><& /Elements/EditCustomField,
+ CustomField => $CF,
+ NamePrefix => "Object-RT::Transaction--CustomField-"
+ &><em><% $CF->FriendlyType %></em>
+</td></tr>
+% } # end if while
+% } # end of if
+% if (exists $session{'Attachments'}) {
+<tr><td><&|/l&>Attached file</&>:</td>
+<td>
+<&|/l&>Check box to delete</&><br />
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
+% } # end of foreach
+</td>
+</tr>
+% } # end of if
+
+ <tr>
+ <td class="label"><&|/l&>Attach</&>:</td>
+ <td class="entry"><input name="Attach" type="file" />
+ <input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" />
+ <input type="hidden" class="hidden" name="UpdateAttach" value="1" /></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Content</&>:</td>
+ <td class="entry"><& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &></td>
+ </tr>
+</table>
+</&>
+
+
+<& /Elements/Submit,
+ Name => 'SubmitTicket',
+ Label => loc('Save Changes'),
+ Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &>
+</form>
+
+<%INIT>
+
+
+
+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;
+
+
+$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
+ $Ticket->CurrentUserHasRight('ModifyTicket') );
+
+$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or
+ $Ticket->CurrentUserHasRight('ModifyTicket') );
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+ if ($key =~ m/^DeleteAttach-(.+)$/) {
+ delete $session{'Attachments'}{$1};
+ }
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+# }}}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) { # attachment?
+ my $attachment = MakeMIMEEntity(
+ AttachmentFieldName => 'Attach'
+ );
+
+ my $file_path = Encode::decode_utf8("$ARGS{'Attach'}");
+ $session{'Attachments'} = {
+ %{$session{'Attachments'} || {}},
+ $file_path => $attachment,
+ };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) {
+ delete $session{'Attachments'};
+}
+# }}}
+
+
+$m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS );
+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){
+ $ARGS{'Owner'} = $owner unless ($Ticket->OwnerObj->id == $owner);
+ }
+
+ }
+
+ 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);
+}
+
+$Ticket->ApplyTransactionBatch;
+
+# If they've gone and moved the ticket to somewhere they can't see, etc...
+# TODO: display the results, even if we can't display the ticket.
+
+unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+}
+
+
+</%INIT>
+
+
+
+<%ARGS>
+$OnlySearchForPeople => undef
+$OnlySearchForGroup => undef
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupString => undef
+$GroupOp => undef
+$GroupField => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/ModifyDates.html b/rt/share/html/Ticket/ModifyDates.html
new file mode 100755
index 0000000..69bfde8
--- /dev/null
+++ b/rt/share/html/Ticket/ModifyDates.html
@@ -0,0 +1,79 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc('Modify dates for #[_1]', $TicketObj->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ current_tab => "Ticket/ModifyDates.html?id=".$TicketObj->Id,
+ Title => loc('Modify dates for #[_1]', $TicketObj->Id) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $TicketObj);
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="ModifyDates.html">
+% $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' &>
+<& Elements/EditDates, TicketObj => $TicketObj &>
+</&>
+<& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes') &>
+</form>
+
+
+<%INIT>
+
+my $TicketObj = LoadTicket($id);
+$m->callback( TicketObj => $TicketObj, ARGSRef => \%ARGS );
+my @results = ProcessTicketDates( TicketObj => $TicketObj, ARGSRef => \%ARGS);
+$TicketObj->ApplyTransactionBatch;
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/ModifyLinks.html b/rt/share/html/Ticket/ModifyLinks.html
new file mode 100755
index 0000000..ae14e93
--- /dev/null
+++ b/rt/share/html/Ticket/ModifyLinks.html
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc("Link ticket #[_1]", $Ticket->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyLinks.html?id=".$Ticket->Id,
+ Title => loc("Link ticket #[_1]", $Ticket->Id) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket);
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="ModifyLinks.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->id%>" />
+% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS );
+% 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/Submit, Name => 'SubmitTicket', Label => loc('Save Changes') &>
+</form>
+
+
+
+
+<%INIT>
+
+my $Ticket = LoadTicket($id);
+
+my @results;
+$m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS, Results => \@results );
+push @results, ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS );
+$Ticket->ApplyTransactionBatch;
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/ModifyPeople.html b/rt/share/html/Ticket/ModifyPeople.html
new file mode 100755
index 0000000..90bca56
--- /dev/null
+++ b/rt/share/html/Ticket/ModifyPeople.html
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyPeople.html?id=".$Ticket->Id,
+ Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket);
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="ModifyPeople.html">
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" />
+% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS );
+<&| /Widgets/TitleBox, title => loc('Modify people related to ticket #[_1]', $Ticket->Id), width => "100%", color=> "#333399", class=>'ticket-info-people' &>
+<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp, GroupString => $GroupString, GroupOp => $GroupOp, GroupField => $GroupField &>
+</&>
+<& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &>
+</form>
+
+<%INIT>
+
+my @results;
+
+my $Ticket = LoadTicket($id);
+$m->callback( TicketObj => $Ticket, ARGSRef => \%ARGS );
+
+# if we're trying to search for watchers and nothing else
+unless ($OnlySearchForPeople or $OnlySearchForGroup) {
+ push @results, ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
+ push @results, ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
+ $Ticket->ApplyTransactionBatch;
+}
+</%INIT>
+
+
+
+<%ARGS>
+$OnlySearchForPeople => undef
+$OnlySearchForGroup => undef
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/share/html/Ticket/Reminders.html b/rt/share/html/Ticket/Reminders.html
new file mode 100755
index 0000000..b799574
--- /dev/null
+++ b/rt/share/html/Ticket/Reminders.html
@@ -0,0 +1,74 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => loc("Reminder ticket #[_1]", $Ticket->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/Reminders.html?id=".$Ticket->Id,
+ Title => loc("Reminders for ticket #[_1]", $Ticket->Id) &>
+
+% $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Ticket => $Ticket);
+
+<form action="<%RT->Config->Get('WebPath')%>/Ticket/Reminders.html" method="post">
+<&|/Widgets/TitleBox, title => loc("Reminders"),
+ class=>'ticket-info-reminders'
+ &>
+
+<& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 1, Edit => 1 &>
+</&>
+<& /Elements/Submit, Label => loc('Save') &>
+</form>
+
+
+<%INIT>
+
+my $Ticket = LoadTicket($id);
+
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Ticket/ShowEmailRecord.html b/rt/share/html/Ticket/ShowEmailRecord.html
new file mode 100644
index 0000000..92f37fb
--- /dev/null
+++ b/rt/share/html/Ticket/ShowEmailRecord.html
@@ -0,0 +1,96 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Attachment => undef
+$Transaction => undef
+</%ARGS>
+<%INIT>
+my $show_content = sub {
+ my $attach = shift;
+ if ( $attach->ContentType =~ m{^(?:text|message)/}i ) {
+ $m->out( $m->interp->apply_escapes( $attach->Content, 'h' ) );
+ return;
+ }
+ my $href = RT->Config->Get('WebPath') .'/Ticket/Attachment/'
+ . $attach->TransactionId .'/'. $attach->id .'/'
+ . $m->interp->apply_escapes( $attach->Filename, 'u' );
+ $m->out( '<a href="'. $href .'">'. loc('download') .'</a>' );
+};
+
+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" );
+ if ( $attach->ContentType =~ m{^multipart/}i ) {
+ my $children = $attach->Children;
+ while ( my $child = $children->Next ) {
+ $show->( $child );
+ }
+ } else {
+ $show_content->( $attach );
+ }
+ $m->out( '</pre></div>' );
+};
+
+my $AttachmentObj = new RT::Attachment($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));
+}
+unless ($AttachmentObj->TransactionId() == $Transaction ) {
+ Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+}
+
+</%INIT>
+<& /Elements/Header, ShowBar => 0 &>
+% $show->( $AttachmentObj );
+</body>
+</html>
+% $m->abort;
diff --git a/rt/share/html/Ticket/Update.html b/rt/share/html/Ticket/Update.html
new file mode 100755
index 0000000..d3c2a09
--- /dev/null
+++ b/rt/share/html/Ticket/Update.html
@@ -0,0 +1,269 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+%# <jesse@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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ Title=> $title &>
+
+% $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Ticket => $TicketObj);
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="Update.html" name="TicketUpdate"
+ method="post" enctype="multipart/form-data">
+% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS, Ticket => $TicketObj );
+<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}||'' %>" />
+
+<& /Elements/GnuPG/SignEncryptWidget:ShowIssues, self => $gnupg_widget &>
+
+<table width="100%" border="0">
+% $m->callback(CallbackName => 'AfterTableOpens', ARGSRef => \%ARGS, Ticket => $TicketObj);
+
+<tr><td class="label"><&|/l&>Status</&>:</td>
+<td>
+<& /Elements/SelectStatus, Name=>"Status", DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)), Default => $ARGS{'Status'} || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
+<span class="label"><&|/l&>Owner</&>:</span>
+<& /Elements/SelectOwner,
+ Name => "Owner",
+ TicketObj => $TicketObj,
+ QueueObj => $TicketObj->QueueObj,
+ DefaultLabel => loc("[_1] (Unchanged)", $TicketObj->OwnerObj->Name),
+ Default => $ARGS{'Owner'}
+&>
+<span class="label"><&|/l&>Worked</&>:</span>
+<& /Elements/EditTimeValue,
+ Name => 'UpdateTimeWorked',
+ Default => $ARGS{UpdateTimeWorked}||'',
+ InUnits => $ARGS{'UpdateTimeWorked-TimeUnits'}||'minutes',
+&>
+</td></tr>
+% my $skip;
+% $m->callback( %ARGS, CallbackName => 'BeforeUpdateType', skip => \$skip );
+% if (!$skip) {
+<input type="hidden" class="hidden" name="id" value="<%$TicketObj->Id%>" /><br />
+% }
+<tr><td class="label"><&|/l&>Update Type</&>:</td>
+<td><select name="UpdateType">
+% if ($CanComment) {
+<option value="private" <% ($ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq "private") ? qq[ selected="selected"] : !$ARGS{'UpdateType'}&&$CommentDefault |n %>><&|/l&>Comments (Not sent to requestors)</&></option>
+% }
+% if ($CanRespond) {
+<option value="response" <% ($ARGS{'UpdateType'} && $ARGS{'UpdateType'} eq "response") ? qq[ selected="selected"] : !$ARGS{'UpdateType'}&&$ResponseDefault |n %>><&|/l&>Reply to requestors</&></option>
+% }
+</select>
+</td></tr>
+<tr><td class="label"><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size="60" value="<% $ARGS{UpdateSubject} || $TicketObj->Subject()%>" /></td></tr>
+
+<& /Ticket/Elements/UpdateCc, %ARGS, TicketObj => $TicketObj &>
+
+<& /Ticket/Elements/EditTransactionCustomFields, %ARGS, TicketObj => $TicketObj &>
+
+% if (exists $session{'Attachments'}) {
+<tr><td><&|/l&>Attached file</&>:</td>
+<td>
+<&|/l&>Check box to delete</&><br />
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
+% } # end of foreach
+</td>
+</tr>
+% } # end of if
+
+<tr><td class="label"><&|/l&>Attach</&>:</td><td><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>
+
+% if ( $gnupg_widget ) {
+<tr><td>&nbsp;</td><td>
+<& /Elements/GnuPG/SignEncryptWidget,
+ self => $gnupg_widget,
+ TicketObj => $TicketObj,
+&>
+</td></tr>
+% }
+
+<tr><td class="label" valign="top"><&|/l&>Message</&>:</td><td>
+% $m->callback( %ARGS, CallbackName => 'BeforeMessageBox' );
+% if (exists $ARGS{UpdateContent}) {
+% # preserve QuoteTransaction so we can use it to set up sane references/in/reply to
+% my $temp = $ARGS{'QuoteTransaction'};
+% delete $ARGS{'QuoteTransaction'};
+<& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0, %ARGS&>
+% $ARGS{'QuoteTransaction'} = $temp;
+% } else {
+<& /Elements/MessageBox, Name=>"UpdateContent", %ARGS &>
+% }
+</td></tr>
+</table>
+
+
+
+
+<& /Elements/Submit, Label => loc('Update Ticket'), Name => 'SubmitTicket' &>
+% if ($TicketObj->CurrentUserHasRight('ShowOutgoingEmail')) {
+<&|/Widgets/TitleBox, title => loc('Scrips and Recipients') &>
+<& /Ticket/Elements/PreviewScrips, TicketObj => $TicketObj, %ARGS &>
+</&>
+
+% }
+</form>
+<%INIT>
+my $CanRespond = 0;
+my $CanComment = 0;
+my $checks_failure = 0;
+my $title;
+
+my $TicketObj = LoadTicket($id);
+
+my @results;
+
+$m->callback( Ticket => $TicketObj, ARGSRef => \%ARGS, results => \@results, CallbackName => 'Initial' );
+
+unless($DefaultStatus){
+ $DefaultStatus=($ARGS{'Status'} ||$TicketObj->Status());
+}
+
+if ($DefaultStatus eq 'new'){
+ $DefaultStatus='open';
+}
+
+if ($DefaultStatus eq 'resolved') {
+ $title = loc("Resolve ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject);
+} else {
+ $title = loc("Update ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject);
+}
+
+# Things needed in the template - we'll do the processing here, just
+# for the convenience:
+
+my ($CommentDefault, $ResponseDefault);
+if ($Action ne 'Respond') {
+ $CommentDefault = qq[ selected="selected"];
+ $ResponseDefault = "";
+} else {
+ $CommentDefault = "";
+ $ResponseDefault = qq[ selected="selected"];
+}
+
+
+
+$CanRespond = 1 if ( $TicketObj->CurrentUserHasRight('ReplyToTicket') or
+ $TicketObj->CurrentUserHasRight('ModifyTicket') );
+
+$CanComment = 1 if ( $TicketObj->CurrentUserHasRight('CommentOnTicket') or
+ $TicketObj->CurrentUserHasRight('ModifyTicket') );
+
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+ if ($key =~ m/^DeleteAttach-(.+)$/) {
+ delete $session{'Attachments'}{$1};
+ }
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+# }}}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) { # attachment?
+ my $attachment = MakeMIMEEntity(
+ AttachmentFieldName => 'Attach'
+ );
+
+ my $file_path = Encode::decode_utf8("$ARGS{'Attach'}");
+ $session{'Attachments'} = {
+ %{$session{'Attachments'} || {}},
+ $file_path => $attachment,
+ };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) {
+ delete $session{'Attachments'};
+}
+# }}}
+
+my $gnupg_widget = $m->comp('/Elements/GnuPG/SignEncryptWidget:new', Arguments => \%ARGS );
+$m->comp( '/Elements/GnuPG/SignEncryptWidget:Process',
+ self => $gnupg_widget,
+ TicketObj => $TicketObj,
+);
+
+if ( $ARGS{'SubmitTicket'} ) {
+ my $CFs = $TicketObj->TransactionCustomFields;
+ my $ValidCFs = $m->comp(
+ '/Elements/ValidateCustomFields',
+ CustomFields => $CFs,
+ NamePrefix => "Object-RT::Transaction--CustomField-",
+ ARGSRef => \%ARGS
+ );
+ unless ( $ValidCFs ) {
+ $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',
+ self => $gnupg_widget,
+ TicketObj => $TicketObj,
+ );
+ $checks_failure = 1 unless $status;
+}
+
+if ( !$checks_failure && exists $ARGS{SubmitTicket} ) {
+ $m->callback( Ticket => $TicketObj, ARGSRef => \%ARGS, CallbackName => 'BeforeDisplay' );
+ return $m->comp('Display.html', TicketObj => $TicketObj, %ARGS);
+}
+</%INIT>
+
+<%ARGS>
+$id => undef
+$Action => undef
+$DefaultStatus => undef
+</%ARGS>