import rt 3.8.7
[freeside.git] / rt / share / html / Elements / RT__Ticket / ColumnMap
diff --git a/rt/share/html/Elements/RT__Ticket/ColumnMap b/rt/share/html/Elements/RT__Ticket/ColumnMap
new file mode 100644 (file)
index 0000000..7df4710
--- /dev/null
@@ -0,0 +1,355 @@
+%# 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>
+$Name => undef
+$Attr => undef
+</%ARGS>
+
+
+<%ONCE>
+my $COLUMN_MAP;
+
+my $LinkCallback = sub {
+    my $method = shift;
+
+    my $mode            = $RT::Ticket::LINKTYPEMAP{$method}{Mode};
+    my $type            = $RT::Ticket::LINKTYPEMAP{$method}{Type};
+    my $other_mode      = ($mode eq "Target" ? "Base" : "Target");
+    my $mode_uri        = $mode.'URI';
+    my $local_type      = 'Local'.$mode;
+
+    return sub {
+        map {
+            \'<a href="',
+            $_->$mode_uri->Resolver->HREF,
+            \'">',
+            ( $_->$mode_uri->IsLocal ? $_->$local_type : $_->$mode ),
+            \'</a><br />',
+        } @{ $_[0]->Links($other_mode,$type)->ItemsArrayRef }
+    }
+};
+
+$COLUMN_MAP = {
+    Queue => {
+        attribute => 'Queue',
+        title     => 'Queue id', # loc
+        value     => sub { return $_[0]->Queue }
+    },
+    QueueName => {
+        attribute => 'Queue',
+        title     => 'Queue', # loc
+        value     => sub { return $_[0]->QueueObj->Name }
+    },
+    OwnerName => {
+        title     => 'Owner', # loc
+        attribute => 'Owner',
+        value     => sub { return $_[0]->OwnerObj->Name }
+    },
+    Status => {
+        title     => 'Status', # loc
+        attribute => 'Status',
+        value     => sub { return loc($_[0]->Status) }
+    },
+    Subject => {
+        title     => 'Subject', # loc
+        attribute => 'Subject',
+        value     => sub { return $_[0]->Subject || "(" . loc('No subject') . ")" }
+    },
+    ExtendedStatus => {
+        title     => 'Status', # loc
+        attribute => 'Status',
+        value     => sub {
+            my $Ticket = shift;
+
+            if ( my $count = $Ticket->HasUnresolvedDependencies ) {
+                if (   $Ticket->HasUnresolvedDependencies( Type => 'approval' )
+                    or $Ticket->HasUnresolvedDependencies( Type => 'code' ) )
+                {
+                    return \'<em>', loc('(pending approval)'), \'</em>';
+                }
+                else {
+                    my $Query = "DependedOnBy = " . $Ticket->id;
+                    $Query .= " AND (" . join(" OR ", map { "Status = '$_'" } RT::Queue->ActiveStatusArray) . ")";
+
+                    my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);
+
+                    return \'<a href="',$SearchURL,\'">', loc('(pending [quant,_1,other ticket])',$count), \'</a>';
+                }
+            }
+            else {
+                return loc( $Ticket->Status );
+            }
+
+          }
+    },
+    Priority => {
+        title     => 'Priority', # loc
+        attribute => 'Priority',
+        value     => sub { return $_[0]->Priority }
+    },
+    InitialPriority => {
+        title     => 'InitialPriority', # loc
+        attribute => 'InitialPriority',
+        name      => 'Initial Priority',
+        value     => sub { return $_[0]->InitialPriority }
+    },
+    FinalPriority => {
+        title     => 'FinalPriority', # loc
+        attribute => 'FinalPriority',
+        name      => 'Final Priority',
+        value     => sub { return $_[0]->FinalPriority }
+    },
+    EffectiveId => {
+        title     => 'EffectiveId', # loc
+        attribute => 'EffectiveId',
+        value     => sub { return $_[0]->EffectiveId }
+    },
+    Type => {
+        title     => 'Type', # loc
+        attribute => 'Type',
+        value     => sub { return $_[0]->Type }
+    },
+    TimeWorked => {
+        attribute => 'TimeWorked',
+        title     => 'Time Worked', # loc
+        value     => sub { return $_[0]->TimeWorked }
+    },
+    TimeLeft => {
+        attribute => 'TimeLeft',
+        title     => 'Time Left', # loc
+        value     => sub { return $_[0]->TimeLeftAsString }
+    },
+    TimeEstimated => {
+        attribute => 'TimeEstimated',
+        title     => 'Time Estimated', # loc
+        value     => sub { return $_[0]->TimeEstimated }
+    },
+    Requestors => {
+        title     => 'Requestors', # loc
+        attribute => 'Requestor.EmailAddress',
+        value     => sub { return $_[0]->Requestors->MemberEmailAddressesAsString }
+    },
+    Cc => {
+        title     => 'Cc', # loc
+        attribute => 'Cc.EmailAddress',
+        value     => sub { return $_[0]->Cc->MemberEmailAddressesAsString }
+    },
+    AdminCc => {
+        title     => 'AdminCc', # loc
+        attribute => 'AdminCc.EmailAddress',
+        value     => sub { return $_[0]->AdminCc->MemberEmailAddressesAsString }
+    },
+    StartsRelative => {
+        title     => 'Starts', # loc
+        attribute => 'Starts',
+        value     => sub { return $_[0]->StartsObj->AgeAsString }
+    },
+    StartedRelative => {
+        title     => 'Started', # loc
+        attribute => 'Started',
+        value     => sub { return $_[0]->StartedObj->AgeAsString }
+    },
+    ToldRelative => {
+        title     => 'Told', # loc
+        attribute => 'Told',
+        value     => sub { return $_[0]->ToldObj->AgeAsString }
+    },
+    DueRelative => {
+        title     => 'Due', # loc
+        attribute => 'Due',
+        value     => sub { 
+            my $date = $_[0]->DueObj;
+            # Highlight the date if it was due in the past, and it's still active
+            if ( $date && $date->Unix > 0 && $date->Diff < 0 && $_[0]->QueueObj->IsActiveStatus($_[0]->Status)) {
+                return (\'<span class="overdue">' , $date->AgeAsString , \'</span>');
+            } else {
+                return $date->AgeAsString;
+            }
+        }
+    },
+    ResolvedRelative => {
+        title     => 'Resolved', # loc
+        attribute => 'Resolved',
+        value     => sub { return $_[0]->ResolvedObj->AgeAsString }
+    },
+    Starts => {
+        title     => 'Starts', # loc
+        attribute => 'Starts',
+        value     => sub { return $_[0]->StartsObj->AsString }
+    },
+    Started => {
+        title     => 'Started', # loc
+        attribute => 'Started',
+        value     => sub { return $_[0]->StartedObj->AsString }
+    },
+    Told => {
+        title     => 'Told', # loc
+        attribute => 'Told',
+        value     => sub { return $_[0]->ToldObj->AsString }
+    },
+    Due => {
+        title     => 'Due', # loc
+        attribute => 'Due',
+        value     => sub { return $_[0]->DueObj->AsString }
+    },
+    Resolved => {
+        title     => 'Resolved', # loc
+        attribute => 'Resolved',
+        value     => sub { return $_[0]->ResolvedObj->AsString }
+    },
+    UpdateStatus => {
+        title => 'New messages', # loc
+        value => sub {
+            my $txn = $_[0]->SeenUpTo or return $_[0]->loc('No');
+            return \('<a href="'. RT->Config->Get('WebPath') .'/Ticket/Display.html?id='
+                . $_[0]->id .'#txn-'. $txn->id .'">'),
+                $_[0]->loc('New'), \'</a>';
+        },
+    },
+    KeyRequestors => {
+        title     => 'Requestors', # loc
+        attribute => 'Requestor.EmailAddress',
+        value => sub {
+            my $t = shift;
+            my @requestors = $t->Requestors->MemberEmailAddresses;
+            for my $email (@requestors)
+            {
+                my %key = RT::Crypt::GnuPG::GetKeyInfo($email);
+                if (!defined $key{'info'}) {
+                    $email .= loc(" (no pubkey!)");
+                }
+                elsif ($key{'info'}{'TrustLevel'} == 0) {
+                    $email .= loc(" (untrusted!)");
+                }
+            }
+            return join ', ', @requestors;
+        }
+    },
+    KeyOwnerName => {
+        title     => 'Owner', # loc
+        attribute => 'Owner',
+        value     => sub {
+            my $t = shift;
+            my $name = $t->OwnerObj->Name;
+            my %key = RT::Crypt::GnuPG::GetKeyInfo($t->OwnerObj->EmailAddress);
+            if (!defined $key{'info'}) {
+                $name .= ' '. loc("(no pubkey!)");
+            }
+            elsif ($key{'info'}{'TrustLevel'} == 0) {
+                $name .= ' '. loc("(untrusted!)");
+            }
+
+            return $name;
+        }
+    },
+
+    # Everything from LINKTYPEMAP
+    (map {
+        $_ => { value => $LinkCallback->( $_ ) }
+    } keys %RT::Ticket::LINKTYPEMAP),
+
+    '_CLASS' => {
+        value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }
+    },
+    '_CHECKBOX' => {
+        attribute => 'checkbox',
+        title => 'Update', # loc
+        align     => 'right',
+        value     => sub { return \('<input type="checkbox" class="checkbox" name="UpdateTicket'.$_[0]->id.'" value="1" checked="checked" />') }
+    },
+
+    CustomField => {
+        attribute => sub { return shift @_ },
+        title     => sub { return pop @_ },
+        value     => sub {
+            # Display custom field contents, separated by newlines.
+            # For Image custom fields we also show a thumbnail here.
+
+            my $values = $_[0]->CustomFieldValues( $_[-1] );
+            my @values = map {
+                (
+                    ($_->CustomFieldObj->Type eq 'Image')
+                        ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ ))
+                        : $_->Content
+                ),
+                \'<br />',
+            } @{ $values->ItemsArrayRef };
+            pop @values; # Remove that last <br />
+            return @values;
+        },
+    },
+    Bookmark => {
+        title => ' ',
+        value => sub {
+            my $bookmark = $m->scomp( '/Ticket/Elements/Bookmark', id => $_[0]->id );
+            # the CollectionAsTable/Row template replaces newlines with <br>
+            $bookmark =~ s/\n//g;
+
+            return \$bookmark;
+        },
+    },
+};
+
+$COLUMN_MAP->{'CF'} = $COLUMN_MAP->{'CustomField'};
+
+# if no GPG support, then KeyOwnerName and KeyRequestors fall back to the regular
+# versions
+if (RT->Config->Get('GnuPG')->{'Enable'}) {
+    require RT::Crypt::GnuPG;
+}
+else {
+    $COLUMN_MAP->{KeyOwnerName} = $COLUMN_MAP->{OwnerName};
+    $COLUMN_MAP->{KeyRequestors} = $COLUMN_MAP->{Requestors};
+}
+</%ONCE>
+<%init>
+$m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
+# backward compatibility
+$m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'ColumnMap' );
+return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
+</%init>