Master to 4.2.8
[usit-rt.git] / share / html / Elements / RT__Ticket / ColumnMap
CommitLineData
84fb5b46
MKG
1%# BEGIN BPS TAGGED BLOCK {{{
2%#
3%# COPYRIGHT:
4%#
320f0092 5%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
84fb5b46
MKG
6%# <sales@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
af59614d 51$GenericMap => {}
84fb5b46
MKG
52</%ARGS>
53
54
55<%ONCE>
56my $COLUMN_MAP;
57
58my $LinkCallback = sub {
59 my $method = shift;
60
af59614d
MKG
61 my $mode = $RT::Link::TYPEMAP{$method}{Mode};
62 my $type = $RT::Link::TYPEMAP{$method}{Type};
84fb5b46
MKG
63 my $other_mode = ($mode eq "Target" ? "Base" : "Target");
64 my $mode_uri = $mode.'URI';
84fb5b46
MKG
65
66 return sub {
af59614d 67 my $ObjectType = $_[2]||'';
84fb5b46
MKG
68 map {
69 \'<a href="',
af59614d 70 $_->$mode_uri->AsHREF,
84fb5b46 71 \'">',
af59614d 72 ( $_->$mode_uri->AsString ),
84fb5b46 73 \'</a><br />',
af59614d
MKG
74 } # if someone says __RefersTo.{Ticket}__ filter for only local links that are tickets
75 grep { $ObjectType
76 ? ( $_->$mode_uri->IsLocal
77 && ( $_->$mode_uri->Object->RecordType eq $ObjectType ))
78 : 1
79 }
80 @{ $_[0]->Links($other_mode,$type)->ItemsArrayRef }
81 }
82};
83
84my $trustSub = sub {
85 my $user = shift;
86 my %key = RT::Crypt->GetKeyInfo( Key => $user->EmailAddress );
87 if (!defined $key{'info'}) {
88 return $m->interp->apply_escapes(' ' . loc("(no pubkey!)"), "h");
89 } elsif ($key{'info'}{'TrustLevel'} == 0) {
90 return $m->interp->apply_escapes(' ' . loc("(untrusted!)"), "h");
84fb5b46
MKG
91 }
92};
93
94$COLUMN_MAP = {
95 Queue => {
96 attribute => 'Queue',
97 title => 'Queue id', # loc
98 value => sub { return $_[0]->Queue }
99 },
100 QueueName => {
101 attribute => 'Queue',
102 title => 'Queue', # loc
103 value => sub { return $_[0]->QueueObj->Name }
104 },
105 OwnerName => {
106 title => 'Owner', # loc
107 attribute => 'Owner',
108 value => sub { return $_[0]->OwnerObj->Name }
109 },
110 Status => {
111 title => 'Status', # loc
112 attribute => 'Status',
113 value => sub { return loc($_[0]->Status) }
114 },
115 Subject => {
116 title => 'Subject', # loc
117 attribute => 'Subject',
118 value => sub { return $_[0]->Subject || "(" . loc('No subject') . ")" }
119 },
120 ExtendedStatus => {
121 title => 'Status', # loc
122 attribute => 'Status',
123 value => sub {
124 my $Ticket = shift;
125
126 if ( my $count = $Ticket->HasUnresolvedDependencies ) {
127 if ( $Ticket->HasUnresolvedDependencies( Type => 'approval' )
128 or $Ticket->HasUnresolvedDependencies( Type => 'code' ) )
129 {
130 return \'<em>', loc('(pending approval)'), \'</em>';
131 }
132 else {
133 my $Query = "DependedOnBy = " . $Ticket->id;
134 $Query .= " AND (" . join(" OR ", map { "Status = '$_'" } RT::Queue->ActiveStatusArray) . ")";
135
136 my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);
137
c33a4027 138 return \'<a href="',$SearchURL,\'">', loc('(pending [quant,_1,other ticket,other tickets])',$count), \'</a>';
84fb5b46
MKG
139 }
140 }
141 else {
142 return loc( $Ticket->Status );
143 }
144
145 }
146 },
147 Priority => {
148 title => 'Priority', # loc
149 attribute => 'Priority',
150 value => sub { return $_[0]->Priority }
151 },
152 InitialPriority => {
153 title => 'InitialPriority', # loc
154 attribute => 'InitialPriority',
155 name => 'Initial Priority',
156 value => sub { return $_[0]->InitialPriority }
157 },
158 FinalPriority => {
159 title => 'FinalPriority', # loc
160 attribute => 'FinalPriority',
161 name => 'Final Priority',
162 value => sub { return $_[0]->FinalPriority }
163 },
164 EffectiveId => {
165 title => 'EffectiveId', # loc
166 attribute => 'EffectiveId',
167 value => sub { return $_[0]->EffectiveId }
168 },
169 Type => {
170 title => 'Type', # loc
171 attribute => 'Type',
172 value => sub { return $_[0]->Type }
173 },
174 TimeWorked => {
175 attribute => 'TimeWorked',
176 title => 'Time Worked', # loc
177 value => sub { return $_[0]->TimeWorked }
178 },
179 TimeLeft => {
180 attribute => 'TimeLeft',
181 title => 'Time Left', # loc
182 value => sub { return $_[0]->TimeLeftAsString }
183 },
184 TimeEstimated => {
185 attribute => 'TimeEstimated',
186 title => 'Time Estimated', # loc
187 value => sub { return $_[0]->TimeEstimated }
188 },
84fb5b46
MKG
189 StartsRelative => {
190 title => 'Starts', # loc
191 attribute => 'Starts',
192 value => sub { return $_[0]->StartsObj->AgeAsString }
193 },
194 StartedRelative => {
195 title => 'Started', # loc
196 attribute => 'Started',
197 value => sub { return $_[0]->StartedObj->AgeAsString }
198 },
199 ToldRelative => {
200 title => 'Told', # loc
201 attribute => 'Told',
202 value => sub { return $_[0]->ToldObj->AgeAsString }
203 },
204 DueRelative => {
205 title => 'Due', # loc
206 attribute => 'Due',
207 value => sub {
208 my $date = $_[0]->DueObj;
209 # Highlight the date if it was due in the past, and it's still active
c33a4027 210 if ( $date && $date->IsSet && $date->Diff < 0 && $_[0]->QueueObj->IsActiveStatus($_[0]->Status)) {
84fb5b46
MKG
211 return (\'<span class="overdue">' , $date->AgeAsString , \'</span>');
212 } else {
213 return $date->AgeAsString;
214 }
215 }
216 },
217 ResolvedRelative => {
218 title => 'Resolved', # loc
219 attribute => 'Resolved',
220 value => sub { return $_[0]->ResolvedObj->AgeAsString }
221 },
222 Starts => {
223 title => 'Starts', # loc
224 attribute => 'Starts',
225 value => sub { return $_[0]->StartsObj->AsString }
226 },
227 Started => {
228 title => 'Started', # loc
229 attribute => 'Started',
230 value => sub { return $_[0]->StartedObj->AsString }
231 },
232 Told => {
233 title => 'Told', # loc
234 attribute => 'Told',
235 value => sub { return $_[0]->ToldObj->AsString }
236 },
237 Due => {
238 title => 'Due', # loc
239 attribute => 'Due',
c33a4027
MKG
240 value => sub {
241 my $date = $_[0]->DueObj;
242 # Highlight the date if it was due in the past, and it's still active
243 if ( $date && $date->IsSet && $date->Diff < 0 && $_[0]->QueueObj->IsActiveStatus($_[0]->Status)) {
244 return (\'<span class="overdue">' , $date->AsString , \'</span>');
245 } else {
246 return $date->AsString;
247 }
248 }
84fb5b46
MKG
249 },
250 Resolved => {
251 title => 'Resolved', # loc
252 attribute => 'Resolved',
253 value => sub { return $_[0]->ResolvedObj->AsString }
254 },
255 UpdateStatus => {
256 title => 'New messages', # loc
257 value => sub {
258 my $txn = $_[0]->SeenUpTo or return $_[0]->loc('No');
259 return \('<a href="'. RT->Config->Get('WebPath') .'/Ticket/Display.html?id='
260 . $_[0]->id .'#txn-'. $txn->id .'">'),
261 $_[0]->loc('New'), \'</a>';
262 },
263 },
264 KeyRequestors => {
265 title => 'Requestors', # loc
266 attribute => 'Requestor.EmailAddress',
af59614d 267 value => sub { return \($m->scomp("/Elements/ShowPrincipal", Object => $_[0]->Requestor, PostUser => $trustSub ) ) }
84fb5b46
MKG
268 },
269 KeyOwnerName => {
270 title => 'Owner', # loc
271 attribute => 'Owner',
272 value => sub {
273 my $t = shift;
274 my $name = $t->OwnerObj->Name;
af59614d 275 my %key = RT::Crypt->GetKeyInfo( Key => $t->OwnerObj->EmailAddress );
84fb5b46
MKG
276 if (!defined $key{'info'}) {
277 $name .= ' '. loc("(no pubkey!)");
278 }
279 elsif ($key{'info'}{'TrustLevel'} == 0) {
280 $name .= ' '. loc("(untrusted!)");
281 }
282
283 return $name;
284 }
285 },
af59614d
MKG
286 KeyOwner => {
287 title => 'Owner', # loc
288 attribute => 'Owner',
289 value => sub { return \($m->scomp("/Elements/ShowPrincipal", Object => $_[0]->OwnerObj, PostUser => $trustSub ) ) }
290 },
84fb5b46
MKG
291
292 # Everything from LINKTYPEMAP
293 (map {
294 $_ => { value => $LinkCallback->( $_ ) }
af59614d 295 } keys %RT::Link::TYPEMAP),
84fb5b46
MKG
296
297 '_CLASS' => {
298 value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }
299 },
300 '_CHECKBOX' => {
301 attribute => 'checkbox',
302 title => 'Update', # loc
303 align => 'right',
304 value => sub { return \('<input type="checkbox" class="checkbox" name="UpdateTicket'.$_[0]->id.'" value="1" checked="checked" />') }
305 },
306
307 Bookmark => {
308 title => ' ',
309 value => sub {
310 my $bookmark = $m->scomp( '/Ticket/Elements/Bookmark', id => $_[0]->id );
311 # the CollectionAsTable/Row template replaces newlines with <br>
312 $bookmark =~ s/\n//g;
313
314 return \$bookmark;
315 },
316 },
317};
84fb5b46
MKG
318</%ONCE>
319<%init>
af59614d
MKG
320# if no encryption support, then KeyOwnerName and KeyRequestors fall back to the regular
321# versions
322unless (RT->Config->Get('Crypt')->{'Enable'}) {
323 $COLUMN_MAP->{KeyOwnerName} = $COLUMN_MAP->{OwnerName};
324 $COLUMN_MAP->{KeyRequestors} = $GenericMap->{Requestors};
325}
326
327$m->callback( GenericMap => $GenericMap, COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
84fb5b46
MKG
328return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
329</%init>