This commit was manufactured by cvs2svn to create tag 'freeside_2_1_0'.
[freeside.git] / rt / share / html / Elements / RT__Ticket / ColumnMap
1 %# BEGIN BPS TAGGED BLOCK {{{
2 %# 
3 %# COPYRIGHT:
4 %# 
5 %# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
6 %#                                          <jesse@bestpractical.com>
7 %# 
8 %# (Except where explicitly superseded by other copyright notices)
9 %# 
10 %# 
11 %# LICENSE:
12 %# 
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
16 %# from www.gnu.org.
17 %# 
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 %# General Public License for more details.
22 %# 
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 %# 02110-1301 or visit their web page on the internet at
27 %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 %# 
29 %# 
30 %# CONTRIBUTION SUBMISSION POLICY:
31 %# 
32 %# (The following paragraph is not intended to limit the rights granted
33 %# to you to modify and distribute this software under the terms of
34 %# the GNU General Public License and is only of importance to you if
35 %# you choose to contribute your changes and enhancements to the
36 %# community by submitting them to Best Practical Solutions, LLC.)
37 %# 
38 %# By intentionally submitting any modifications, corrections or
39 %# derivatives to this work, or any other work intended for use with
40 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 %# you are the copyright holder for those contributions and you grant
42 %# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 %# royalty-free, perpetual, license to use, copy, create derivative
44 %# works based on those contributions, and sublicense and distribute
45 %# those contributions and any derivatives thereof.
46 %# 
47 %# END BPS TAGGED BLOCK }}}
48 <%ARGS>
49 $Name => undef
50 $Attr => undef
51 </%ARGS>
52
53
54 <%ONCE>
55 my $COLUMN_MAP;
56
57 my $LinkCallback = sub {
58     my $method = shift;
59
60     my $mode            = $RT::Ticket::LINKTYPEMAP{$method}{Mode};
61     my $type            = $RT::Ticket::LINKTYPEMAP{$method}{Type};
62     my $other_mode      = ($mode eq "Target" ? "Base" : "Target");
63     my $mode_uri        = $mode.'URI';
64     my $local_type      = 'Local'.$mode;
65
66     return sub {
67         map {
68             \'<a href="',
69             $_->$mode_uri->Resolver->HREF,
70             \'">',
71             ( $_->$mode_uri->IsLocal ? $_->$local_type : $_->$mode ),
72             \'</a><br />',
73         } @{ $_[0]->Links($other_mode,$type)->ItemsArrayRef }
74     }
75 };
76
77 $COLUMN_MAP = {
78     Queue => {
79         attribute => 'Queue',
80         title     => 'Queue id', # loc
81         value     => sub { return $_[0]->Queue }
82     },
83     QueueName => {
84         attribute => 'Queue',
85         title     => 'Queue', # loc
86         value     => sub { return $_[0]->QueueObj->Name }
87     },
88     OwnerName => {
89         title     => 'Owner', # loc
90         attribute => 'Owner',
91         value     => sub { return $_[0]->OwnerObj->Name }
92     },
93     Status => {
94         title     => 'Status', # loc
95         attribute => 'Status',
96         value     => sub { return loc($_[0]->Status) }
97     },
98     Subject => {
99         title     => 'Subject', # loc
100         attribute => 'Subject',
101         value     => sub { return $_[0]->Subject || "(" . loc('No subject') . ")" }
102     },
103     ExtendedStatus => {
104         title     => 'Status', # loc
105         attribute => 'Status',
106         value     => sub {
107             my $Ticket = shift;
108
109             if ( my $count = $Ticket->HasUnresolvedDependencies ) {
110                 if (   $Ticket->HasUnresolvedDependencies( Type => 'approval' )
111                     or $Ticket->HasUnresolvedDependencies( Type => 'code' ) )
112                 {
113                     return \'<em>', loc('(pending approval)'), \'</em>';
114                 }
115                 else {
116                     my $Query = "DependedOnBy = " . $Ticket->id;
117                     $Query .= " AND (" . join(" OR ", map { "Status = '$_'" } RT::Queue->ActiveStatusArray) . ")";
118
119                     my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);
120
121                     return \'<a href="',$SearchURL,\'">', loc('(pending [quant,_1,other ticket])',$count), \'</a>';
122                 }
123             }
124             else {
125                 return loc( $Ticket->Status );
126             }
127
128           }
129     },
130     Priority => {
131         title     => 'Priority', # loc
132         attribute => 'Priority',
133         value     => sub { return $_[0]->Priority }
134     },
135     InitialPriority => {
136         title     => 'InitialPriority', # loc
137         attribute => 'InitialPriority',
138         name      => 'Initial Priority',
139         value     => sub { return $_[0]->InitialPriority }
140     },
141     FinalPriority => {
142         title     => 'FinalPriority', # loc
143         attribute => 'FinalPriority',
144         name      => 'Final Priority',
145         value     => sub { return $_[0]->FinalPriority }
146     },
147     EffectiveId => {
148         title     => 'EffectiveId', # loc
149         attribute => 'EffectiveId',
150         value     => sub { return $_[0]->EffectiveId }
151     },
152     Type => {
153         title     => 'Type', # loc
154         attribute => 'Type',
155         value     => sub { return $_[0]->Type }
156     },
157     TimeWorked => {
158         attribute => 'TimeWorked',
159         title     => 'Time Worked', # loc
160         value     => sub { return $_[0]->TimeWorked }
161     },
162     TimeLeft => {
163         attribute => 'TimeLeft',
164         title     => 'Time Left', # loc
165         value     => sub { return $_[0]->TimeLeftAsString }
166     },
167     TimeEstimated => {
168         attribute => 'TimeEstimated',
169         title     => 'Time Estimated', # loc
170         value     => sub { return $_[0]->TimeEstimated }
171     },
172     Requestors => {
173         title     => 'Requestors', # loc
174         attribute => 'Requestor.EmailAddress',
175         value     => sub { return $_[0]->Requestors->MemberEmailAddressesAsString }
176     },
177     Cc => {
178         title     => 'Cc', # loc
179         attribute => 'Cc.EmailAddress',
180         value     => sub { return $_[0]->Cc->MemberEmailAddressesAsString }
181     },
182     AdminCc => {
183         title     => 'AdminCc', # loc
184         attribute => 'AdminCc.EmailAddress',
185         value     => sub { return $_[0]->AdminCc->MemberEmailAddressesAsString }
186     },
187     StartsRelative => {
188         title     => 'Starts', # loc
189         attribute => 'Starts',
190         value     => sub { return $_[0]->StartsObj->AgeAsString }
191     },
192     StartedRelative => {
193         title     => 'Started', # loc
194         attribute => 'Started',
195         value     => sub { return $_[0]->StartedObj->AgeAsString }
196     },
197     ToldRelative => {
198         title     => 'Told', # loc
199         attribute => 'Told',
200         value     => sub { return $_[0]->ToldObj->AgeAsString }
201     },
202     DueRelative => {
203         title     => 'Due', # loc
204         attribute => 'Due',
205         value     => sub { 
206             my $date = $_[0]->DueObj;
207             # Highlight the date if it was due in the past, and it's still active
208             if ( $date && $date->Unix > 0 && $date->Diff < 0 && $_[0]->QueueObj->IsActiveStatus($_[0]->Status)) {
209                 return (\'<span class="overdue">' , $date->AgeAsString , \'</span>');
210             } else {
211                 return $date->AgeAsString;
212             }
213         }
214     },
215     ResolvedRelative => {
216         title     => 'Resolved', # loc
217         attribute => 'Resolved',
218         value     => sub { return $_[0]->ResolvedObj->AgeAsString }
219     },
220     Starts => {
221         title     => 'Starts', # loc
222         attribute => 'Starts',
223         value     => sub { return $_[0]->StartsObj->AsString }
224     },
225     Started => {
226         title     => 'Started', # loc
227         attribute => 'Started',
228         value     => sub { return $_[0]->StartedObj->AsString }
229     },
230     Told => {
231         title     => 'Told', # loc
232         attribute => 'Told',
233         value     => sub { return $_[0]->ToldObj->AsString }
234     },
235     Due => {
236         title     => 'Due', # loc
237         attribute => 'Due',
238         value     => sub { return $_[0]->DueObj->AsString }
239     },
240     Resolved => {
241         title     => 'Resolved', # loc
242         attribute => 'Resolved',
243         value     => sub { return $_[0]->ResolvedObj->AsString }
244     },
245     UpdateStatus => {
246         title => 'New messages', # loc
247         value => sub {
248             my $txn = $_[0]->SeenUpTo or return $_[0]->loc('No');
249             return \('<a href="'. RT->Config->Get('WebPath') .'/Ticket/Display.html?id='
250                 . $_[0]->id .'#txn-'. $txn->id .'">'),
251                 $_[0]->loc('New'), \'</a>';
252         },
253     },
254     KeyRequestors => {
255         title     => 'Requestors', # loc
256         attribute => 'Requestor.EmailAddress',
257         value => sub {
258             my $t = shift;
259             my @requestors = $t->Requestors->MemberEmailAddresses;
260             for my $email (@requestors)
261             {
262                 my %key = RT::Crypt::GnuPG::GetKeyInfo($email);
263                 if (!defined $key{'info'}) {
264                     $email .= loc(" (no pubkey!)");
265                 }
266                 elsif ($key{'info'}{'TrustLevel'} == 0) {
267                     $email .= loc(" (untrusted!)");
268                 }
269             }
270             return join ', ', @requestors;
271         }
272     },
273     KeyOwnerName => {
274         title     => 'Owner', # loc
275         attribute => 'Owner',
276         value     => sub {
277             my $t = shift;
278             my $name = $t->OwnerObj->Name;
279             my %key = RT::Crypt::GnuPG::GetKeyInfo($t->OwnerObj->EmailAddress);
280             if (!defined $key{'info'}) {
281                 $name .= ' '. loc("(no pubkey!)");
282             }
283             elsif ($key{'info'}{'TrustLevel'} == 0) {
284                 $name .= ' '. loc("(untrusted!)");
285             }
286
287             return $name;
288         }
289     },
290
291     # Everything from LINKTYPEMAP
292     (map {
293         $_ => { value => $LinkCallback->( $_ ) }
294     } keys %RT::Ticket::LINKTYPEMAP),
295
296     '_CLASS' => {
297         value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }
298     },
299     '_CHECKBOX' => {
300         attribute => 'checkbox',
301         title => 'Update', # loc
302         align     => 'right',
303         value     => sub { return \('<input type="checkbox" class="checkbox" name="UpdateTicket'.$_[0]->id.'" value="1" checked="checked" />') }
304     },
305
306     Bookmark => {
307         title => ' ',
308         value => sub {
309             my $bookmark = $m->scomp( '/Ticket/Elements/Bookmark', id => $_[0]->id );
310             # the CollectionAsTable/Row template replaces newlines with <br>
311             $bookmark =~ s/\n//g;
312
313             return \$bookmark;
314         },
315     },
316 };
317
318 # if no GPG support, then KeyOwnerName and KeyRequestors fall back to the regular
319 # versions
320 if (RT->Config->Get('GnuPG')->{'Enable'}) {
321     require RT::Crypt::GnuPG;
322 }
323 else {
324     $COLUMN_MAP->{KeyOwnerName} = $COLUMN_MAP->{OwnerName};
325     $COLUMN_MAP->{KeyRequestors} = $COLUMN_MAP->{Requestors};
326 }
327 </%ONCE>
328 <%init>
329 $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
330 # backward compatibility
331 $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'ColumnMap' );
332 return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
333 </%init>