Side-by-side ticket screen for RT 3.6.5

I recently created the side-by-side ticket screen that Steve Turner
contributed to the mailing list. It is awesome! Thanks for putting
this up there, my helpdesk staff love it. I did run into a few things
that I had to do in order to get it working smoothly on RT 3.6.5 so I
thought I would share my findings for anyone that wants to create this
on the new distribution. I included all my notes on it so hopefully it
will help make it easier for the next guy. Thanks again Steve!

The basic idea is to provide a ticket update screen that showed the
ticket history, and to have ticket details and history

“side-by-side” for easier viewing. I based this screen on the existing
Jumbo screen. Here are the essential steps:

  1. Copied the Jumbo screen (Ticket/ModifyAll.html). I called the new
    page ModifyAllHistory.html.

  2. Removed the portions of the page I didn’t want. For example, I didn’t
    want the Links section on the Side by Side screen.

So I simply removed this part of the page:

<& /Elements/TitleBoxStart, title => loc(‘Links’), color => “#336633”&>

<& /Elements/EditLinks, Object => $Ticket, Merge => 1 &>

<& /Elements/TitleBoxEnd &>

  1. Changed the layout of the page to be a two-column, single-row table,
    with the left column containing the desired elements

from the Jumbo page and the right column holding the ticket history.

Briefly, the new page layout looks like this (everything else outside
the element remains the same).

----> BEGIN MODS

-----> All the ticket update elements from Jumbo that you want to keep

<& /Ticket/Elements/ShowHistory ,

Ticket => $Ticket,

Tickets => $Tickets,

Collapsed => $ARGS{'Collapsed'},

ShowHeaders => $ARGS{'ShowHeaders'},

Attachments => $attachments,

AttachmentContent => $attachment_content,

&>

----> END MODS

<& /Elements/Submit,

Label => loc('Save Changes'),

Caption => loc("If you've updated anything above, be sure to"),

color => “#333399” &>

******* So my complete local/html/Ticket/ModifyAllHistory.html file
looks like this: (I bolded everything that I added or changed to this
file from the original) *****************

<& /Elements/Header, Title => loc(“Ticket #[_1] Side-by-Side update:
[_2]”, $Ticket->Id, $Ticket->Subject) &>

<& /Ticket/Elements/Tabs,

Ticket => $Ticket, 

current_tab => "Ticket/ModifyAllHistory.html?id=".$Ticket->Id, 

Title => loc("Ticket #[_1] Side-by-Side update: [_2]", $Ticket->Id,

$Ticket->Subject) &>

<& /Elements/ListActions, actions => @results &>

<& /Elements/Callback, _CallbackName => ‘FormStart’,ARGSRef =>%ARGS &>

<&| /Widgets/TitleBox, title => loc(‘Modify ticket # [_1]’, $Ticket->Id)
&>

<& Elements/EditBasics, TicketObj => $Ticket &>

<& Elements/EditCustomFields, TicketObj => $Ticket &>

</&>


<&| /Widgets/TitleBox, title => loc(‘Dates’) &>

<& Elements/EditDates, TicketObj => $Ticket &>

</&>


<&| /Widgets/TitleBox, title => loc(‘People’) &>

<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField,
UserString => $UserString, UserOp => $UserOp &>

</&>


<&| /Widgets/TitleBox, title => loc(‘Update ticket’) &>

<td class="label"><&|/l&>Update Type</&>:</td>

<td class="entry">

  <select name="UpdateType">

% if ($CanComment) {

    <option value="private" ><&|/l&>Comments (Not sent to

requestors)</&>

% }

% if ($CanRespond) {

    <option value="response"><&|/l&>Reply to requestors</&></option>

% }

  </select> 

</td>
<td class="label"><&|/l&>Subject</&>:</td>

<td class="entry"><input name="UpdateSubject" size="60"

value="<%$Ticket->Subject%>" />

% if (my $TxnCFs = $Ticket->TransactionCustomFields) {

% while (my $CF = $TxnCFs->Next()) {

% } # end if while

% } # end of if

<td class="label"><&|/l&>Attach</&>:</td>

<td class="entry"><input name="UpdateAttachment" type="file" /></td>
<td class="labeltop"><&|/l&>Content</&>:</td>

<td class="entry"><& /Elements/MessageBox, Name=>"UpdateContent",

QuoteTransaction=>$ARGS{QuoteTransaction} &>

<% $CF->Name %>: <& /Elements/EditCustomField,
CustomField => $CF, 

NamePrefix => "Object-RT::Transaction--CustomField-"

&><em><% $CF->FriendlyType %></em></td>

</&>

<& /Ticket/Elements/ShowHistory ,

Ticket => $Ticket,

Collapsed => $ARGS{'Collapsed'},

ShowHeaders => $ARGS{'ShowHeaders'},

&>

<& /Elements/Submit,

Label => loc('Save Changes'), 

Caption => loc("If you've updated anything above, be sure to"),

color => “#333399” &>

<%INIT>

my $Ticket = LoadTicket($id);

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') );

$m->comp(’/Elements/Callback’, TicketObj => $Ticket, ARGSRef => %ARGS);

my (@wresults, @results, @dresults, @lresults, @cf_results);

unless ($OnlySearchForPeople) {

# 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);

    }



}



@wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef =>

%ARGS);

@cf_results = ProcessObjectCustomFieldUpdates( Object => $Ticket,
ARGSRef => %ARGS);

@dresults = ProcessTicketDates( TicketObj => $Ticket, ARGSRef =>

%ARGS);

@lresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef =>

%ARGS);

if ($ARGS{'UpdateAttachment'}) {

    my $subject = "$ARGS{'UpdateAttachment'}";

    # since CGI.pm deutf8izes the magic field, we need to add it

back.

    Encode::_utf8_on($subject);

    # strip leading directories

    $subject =~ s#^.*[\\/]##;



    my $attachment = MakeMIMEEntity(

       Subject             => $subject,

       Body                => "",

       AttachmentFieldName => 'UpdateAttachment'

    );

            delete $ARGS{'UpdateAttachment'};

            $ARGS{'UpdateAttachments'}->{ $subject } = $attachment;

}



$ARGS{'UpdateContent'} =~ s/\r+\n/\n/g if $ARGS{'UpdateContent'};



if ($ARGS{'UpdateAttachments'} || ( $ARGS{'UpdateContent'} &&

$ARGS{‘UpdateContent’} ne “-- \n” .

$session{‘CurrentUser’}->UserObj->Signature)) {

             ProcessUpdateMessage(TicketObj => $Ticket,

ARGSRef=>%ARGS, Actions=>@results);

            }

@results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef =>

%ARGS);

}

push @results, @wresults;

push @results, @dresults;

push @results, @lresults;

push @results, @cf_results;

undef so that TransactionBatch scrips run and update the ticket

$Ticket = undef;

$Ticket = LoadTicket($id);

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

$UserField => undef

$UserOp => undef

$UserString => undef

$id => undef

</%ARGS>

  1. Edit/create local/html/Ticket/Elements/Tabs, and add this line:

_B => { title => loc(‘Side-by-Side’),

        path  => "Ticket/ModifyAllHistory.html?id=" . $id, },
  1. Create /local/html/Tickets/Elements/ShowHistory (copy from
    /share/html…) and edit the line:

From:

$URIFile => $RT::WebPath."/Ticket/Display.html"

To Read:

$URIFile => $RT::WebPath."/Ticket/ModifyAllHistory.html"

Sean McCreadie

IT Support

Canyon Partners, LLC