5 * Copyright 1999-2001 (c) VA Linux Systems
6 * Copyright 2010 Roland Mas
7 * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
9 * This file is part of FusionForge. FusionForge is free software;
10 * you can redistribute it and/or modify it under the terms of the
11 * GNU General Public License as published by the Free Software
12 * Foundation; either version 2 of the Licence, or (at your option)
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 require_once $gfcommon.'tracker/ArtifactFactory.class.php';
26 require_once $gfcommon.'tracker/ArtifactQuery.class.php';
28 // make sure this person has permission to view artifacts
30 session_require_perm ('tracker', $ath->getID(), 'read') ;
32 $query_id = getIntFromRequest('query_id');
33 $start = getIntFromRequest('start');
37 // The browse page can be powered by a pre-saved query
38 // or by select boxes chosen by the user
40 // If there is a $query_id coming from the request OR the pref
41 // was already saved, use the artifact factory that way.
43 // If the query_id = -1, unset the pref and use regular browse boxes
45 if (session_loggedin()) {
46 $u =& session_get_user();
47 if (getStringFromRequest('setpaging')) {
48 /* store paging preferences */
49 $paging = getIntFromRequest('nres');
53 $u->setPreference("paging", $paging);
57 if ($query_id == '-1') {
58 $u->setPreference('art_query'.$ath->getID(),'');
60 $aq = new ArtifactQuery($ath,$query_id);
61 if (!$aq || !is_object($aq)) {
62 exit_error($aq->getErrorMessage(),'tracker');
67 $query_id=$u->getPreference('art_query'.$ath->getID(),'');
69 } elseif ($query_id) {
70 // If user is not logged, then use a cookie to store the current query.
71 if (isset($_COOKIE["GFTrackerQuery"])) {
72 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
74 $gf_tracker = array();
76 $gf_tracker[$ath->getID()] = $query_id;
77 // Send the query_id as a cookie to save it.
78 setcookie("GFTrackerQuery", serialize($gf_tracker));
79 $_COOKIE["GFTrackerQuery"] = serialize($gf_tracker);
80 } elseif (isset($_COOKIE["GFTrackerQuery"])) {
81 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
82 $query_id = (int)$gf_tracker[$ath->getID()];
85 $af = new ArtifactFactory($ath);
87 if (!$af || !is_object($af)) {
88 exit_error(_('Could Not Get Factory'),'tracker');
89 } elseif ($af->isError()) {
90 exit_error($af->getErrorMessage(),'tracker');
93 if (!isset($_sort_col)) {
94 /* default sort order: highest priority first */
95 $_sort_col = 'priority';
98 $offset = getStringFromRequest('offset');
99 $_sort_col = getStringFromRequest('_sort_col',$_sort_col);
100 $_sort_ord = getStringFromRequest('_sort_ord',$_sort_ord);
101 $max_rows = getIntFromRequest('max_rows', 25);
102 $set = getStringFromRequest('set');
103 $_assigned_to = getIntFromRequest('_assigned_to');
104 $_status = getIntFromRequest('_status');
105 $_extra_fields = array() ;
106 $aux_extra_fields = array() ;
108 if ($set == 'custom') {
109 /* may be past in next/prev url */
110 $i = $ath->getCustomStatusField();
111 $tmp_extra_fields = getArrayFromRequest('extra_fields');
112 if (isset($tmp_extra_fields[$i])) {
113 $_extra_fields[$i] = $tmp_extra_fields[$i];
117 if (is_array($_extra_fields)){
118 $keys=array_keys($_extra_fields);
119 foreach ($keys as $key) {
120 if ($_extra_fields[$key] != 'Array') {
121 $aux_extra_fields[$key] = $_extra_fields[$key];
125 if (isset($_extra_fields)){
126 $aux_extra_fields = $_extra_fields;
128 $aux_extra_fields = '';
132 $af->setup($offset,$_sort_col,$_sort_ord,$paging,$set,$_assigned_to,$_status,$aux_extra_fields);
134 // These vals are sanitized and/or retrieved from ArtifactFactory stored settings
136 $_sort_col=$af->order_col;
137 $_sort_ord=$af->sort;
138 $_status=$af->status;
139 $_assigned_to=$af->assigned_to;
140 $_extra_fields=$af->extra_fields;
142 $art_arr = $af->getArtifacts();
144 if (!$art_arr && $af->isError()) {
145 exit_error($af->getErrorMessage(),'tracker');
148 //build page title to make bookmarking easier
149 //if a user was selected, add the user_name to the title
151 use_javascript('/tabber/tabber.js');
153 $ath->header(array('atid'=>$ath->getID(), 'title'=>$ath->getName()));
157 * Build the powerful browsing options pop-up boxes
162 // creating a custom technician box which includes "any" and "unassigned"
164 $engine = RBACEngine::getInstance () ;
165 $techs = $engine->getUsersByAllowedAction ('tracker', $ath->getID(), 'tech') ;
167 $tech_id_arr = array () ;
168 $tech_name_arr = array () ;
170 foreach ($techs as $tech) {
171 $tech_id_arr[] = $tech->getID() ;
172 $tech_name_arr[] = $tech->getRealName() ;
174 $tech_id_arr[]='0'; //this will be the 'any' row
175 $tech_name_arr[]=_('Any');
177 if (is_array($_assigned_to)) {
180 $tech_box=html_build_select_box_from_arrays ($tech_id_arr,$tech_name_arr,'_assigned_to',$_assigned_to,true,_('Unassigned'));
184 // custom order by arrays to build a pop-up box
186 $order_name_arr=array();
187 $order_name_arr[]=_('ID');
188 $order_name_arr[]=_('Priority');
189 $order_name_arr[]=_('Summary');
190 $order_name_arr[]=_('Open Date');
191 $order_name_arr[]=_('Last Modified Date');
192 $order_name_arr[]=_('Close Date');
193 $order_name_arr[]=_('Submitter');
194 $order_name_arr[]=_('Assignee');
198 $order_arr[]='artifact_id';
199 $order_arr[]='priority';
200 $order_arr[]='summary';
201 $order_arr[]='open_date';
202 $order_arr[]='last_modified_date';
203 $order_arr[]='close_date';
204 $order_arr[]='submitted_by';
205 $order_arr[]='assigned_to';
208 // custom sort arrays to build pop-up box
210 $sort_name_arr=array();
211 $sort_name_arr[]=_('Ascending');
212 $sort_name_arr[]=_('Descending');
219 // custom changed arrays to build pop-up box
221 $changed_name_arr=array();
222 $changed_name_arr[]=_('Any changes');
223 $changed_name_arr[]=_('Last 24H');
224 $changed_name_arr[]=_('Last 7days');
225 $changed_name_arr[]=_('Last 2weeks');
226 $changed_name_arr[]=_('Last 1month');
228 $changed_arr=array();
229 $changed_arr[]= 0x7fffffff; // Any
230 $changed_arr[]= 3600 * 24; // 24 hour
231 $changed_arr[]= 3600 * 24 * 7; // 1 week
232 $changed_arr[]= 3600 * 24 * 14;// 2 week
233 $changed_arr[]= 3600 * 24 * 30;// 1 month
235 if ($art_arr && ($art_cnt = count($art_arr)) > 0) {
236 $focus = getIntFromRequest('focus');
243 if (session_loggedin()) {
244 /* logged in users get configurable paging */
245 $paging = $u->getPreference("paging");
246 echo '<form action="'. getStringFromServer('PHP_SELF') .'?group_id='.$group_id.'&atid='.$ath->getID().'&start='.
247 $start.'" method="post">'."\n";
254 for ($i = 0; $i < $art_cnt; ++$i)
255 if ($art_arr[$i]->getID() == $focus) {
260 $max = ($art_cnt > ($start + $paging)) ? ($start + $paging) : $art_cnt;
265 printf('<p>' . _('Displaying results %1$d‒%2$d out of %3$d total.'),
266 $start + 1, $max, $art_cnt);
267 if (session_loggedin()) {
268 printf(' ' . _('Displaying %2$s results.') . "\n\t<input " .
269 'type="submit" name="setpaging" value="%1$s" />' .
270 "\n</p>\n</form>\n", _('Change'),
271 html_build_select_box_from_array(array(
272 '10', '25', '50', '100', '1000'), 'nres', $paging, 1));
279 * Show the free-form text submitted by the project admin
281 echo $ath->renderBrowseInstructions();
284 // statuses can be custom in GForge 4.5+
286 if ($ath->usesCustomStatuses()) {
287 $aux_extra_fields = array();
288 if (is_array($_extra_fields)){
289 $keys=array_keys($_extra_fields);
290 foreach ($keys as $key) {
291 if (!is_array($_extra_fields[$key])) {
292 $aux_extra_fields[$key] = $_extra_fields[$key];
296 $aux_extra_fields = $_extra_fields;
298 $status_box=$ath->renderSelect ($ath->getCustomStatusField(),$aux_extra_fields[$ath->getCustomStatusField()],false,'',true,_('Any'));
300 if (is_array($_status)) {
303 $status_box = $ath->statusBox('_status',$_status,true,_('Any'));
307 $proj_name = $group->getUnixName();
308 $proj_url = util_make_url_g($group->getUnixName(),$group_id);
309 // the tracker's URIs are constructed in order to support addition of an OSLC-CM REST server
310 // inside /tracker/cm/. There each tracker has a URL in the form .../project/PROJ_NAME/atid/ATID
311 $tracker_stdzd_uri = util_make_url('/tracker/cm/project/'. $proj_name .'/atid/'. $ath->getID());
312 print '<div about="'. $tracker_stdzd_uri
313 .'" typeof="sioc:Container">'."\n";
314 print '<span rel="http://www.w3.org/2002/07/owl#sameAs" resource="" />'."\n";
315 print '<span rev="doap:bug-database sioc:space_of" resource="'. $proj_url .'" />'."\n";
316 print "</div>\n"; // end of about
319 <div id="tabber" class="tabber">
320 <div class="tabbertab" title="'._('Advanced queries').'">';
322 if (session_loggedin()) {
323 $res = db_query_params ('SELECT artifact_query_id,query_name, CASE WHEN query_type>0 THEN 1 ELSE 0 END as type
325 WHERE group_artifact_id=$1 AND (user_id=$2 OR query_type>0)
326 ORDER BY type ASC, query_name ASC',
327 array ($ath->getID(),
330 $res = db_query_params ('SELECT artifact_query_id,query_name, CASE WHEN query_type>0 THEN 1 ELSE 0 END as type
332 WHERE group_artifact_id=$1 AND query_type>0
333 ORDER BY type ASC, query_name ASC',
334 array ($ath->getID()));
338 if (db_numrows($res)>0) {
339 echo '<form action="'. getStringFromServer('PHP_SELF') .'" method="get">';
340 echo '<input type="hidden" name="group_id" value="'.$group_id.'" />';
341 echo '<input type="hidden" name="atid" value="'.$ath->getID().'" />';
342 echo '<input type="hidden" name="power_query" value="1" />';
343 echo ' <table width="100%" cellspacing="0">
347 $optgroup['key'] = 'type';
348 $optgroup['values'][0] = 'Private queries';
349 $optgroup['values'][1] = 'Project queries';
350 echo '<span style="font-size:smaller">';
351 echo '<select name="query_id" id="query_id">';
352 echo '<option value="100">Select One</option>';
354 $selected = $af->getDefaultQuery();
355 while ($row = db_fetch_array($res)) {
356 if ($current != $row['type']) {
359 $label = $row['type'] ? 'Project' : 'Private';
360 echo '<optgroup label="'.$label.'">';
361 $current = $row['type'];
363 echo '<option value="'.$row['artifact_query_id'].'"';
364 if ($row['artifact_query_id'] == $selected)
365 echo ' selected="selected"';
366 echo '>'. $row['query_name'] .'</option>'."\n";
372 <noscript><input type="submit" name="run" value="'._('Power Query').'" /></noscript>
373 <a href="/tracker/?atid='. $ath->getID().'&group_id='.$group_id.'&func=query">'.
374 _('Build Query').'</a>
378 <script language="JavaScript" type="text/javascript">/* <![CDATA[ */
379 $('#query_id').change(function() {
380 location.href = '<?php echo getStringFromServer('PHP_SELF') .'?group_id='.$group_id.'&atid='.$ath->getID().'&power_query=1&query_id=' ?>'+$('#query_id').val();
386 <a href="/tracker/?atid='. $ath->getID().'&group_id='.$group_id.'&func=query">'._('Build Query').'</a></strong>';
390 <div class="tabbertab'.($af->query_type == 'custom' ? ' tabbertabdefault' : '').'" title="'._('Simple Filtering and Sorting').'">
391 <form action="'. getStringFromServer('PHP_SELF') .'?group_id='.$group_id.'&atid='.$ath->getID().'" method="post">
392 <input type="hidden" name="query_id" value="-1" />
393 <input type="hidden" name="set" value="custom" />
394 <table width="100%" cellspacing="0">
397 '._('Assignee').': '. $tech_box .'
400 '._('State').': '. $status_box .'
404 // Compute the list of fields which can be sorted.
405 $efarr = $ath->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_TEXT,
406 ARTIFACT_EXTRAFIELDTYPE_TEXTAREA,
407 ARTIFACT_EXTRAFIELDTYPE_INTEGER,
408 ARTIFACT_EXTRAFIELDTYPE_SELECT,
409 ARTIFACT_EXTRAFIELDTYPE_RADIO,
410 ARTIFACT_EXTRAFIELDTYPE_STATUS));
411 $keys=array_keys($efarr);
412 for ($k=0; $k<count($keys); $k++) {
414 $order_name_arr[] = $efarr[$i]['field_name'];
415 $order_arr[] = $efarr[$i]['extra_field_id'];
419 html_build_select_box_from_arrays($order_arr,$order_name_arr,'_sort_col',$_sort_col,false) .
420 html_build_select_box_from_arrays($sort_arr,$sort_name_arr,'_sort_ord',$_sort_ord,false) .
421 '<input type="submit" name="submit" value="'._('Quick Browse').'" />';
429 if ($af->query_type == 'default') {
430 echo '<div class="tabbertab tabbertabdefault" title="'._('Default').'">';
431 echo '<strong>'._('Viewing only opened records by default, use \'Advanced queries\' or \'Simple Filtering and Sorting\' to change.').'</strong>';
437 $art_cnt = count($art_arr);
438 if ($art_arr && $art_cnt > 0) {
441 $aq = new ArtifactQuery($ath,$query_id);
442 $has_bargraph = (in_array('bargraph', $aq->getQueryOptions()));
444 $has_bargraph = false;
448 // Display the roadmap block based on the values of the Status field.
449 $colors = array('#a71d16', '#ffa0a0', '#f5f5b5', '#bae0ba', '#16a716');
452 foreach($art_arr as $art) {
453 if ($ath->usesCustomStatuses()) {
454 $custom_id = $ath->getCustomStatusField();
455 $extra_data = $art->getExtraFieldDataText();
456 @$count[ $extra_data[$custom_id]['value'] ]++;
458 @$count[ $art->getStatusName()]++;
461 foreach($count as $n => $c) {
462 $percent[$n] = round(100*$c/$art_cnt);
464 if ($ath->getCustomStatusField()) {
465 $efarr = $ath->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_STATUS));
466 $keys=array_keys($efarr);
467 $field_id = $keys[0];
468 $custom_states = $ath->getExtraFieldElements($field_id);
470 if (is_array($custom_states)) {
471 foreach($custom_states as $state) {
472 $states[] = $state['element_name'];
476 $colors = array('#ffa0a0', '#bae0ba');
477 $res = $ath->getStatuses();
478 while ($row = db_fetch_array($res)) {
479 $states[] = $row['status_name'];
486 if (is_array($states)) {
487 foreach($states as $name) {
489 $graph .= '<td style="background: '.$colors[$i].'; width: '.$percent[$name].'%;"> </td>';
490 $legend .= '<td style="white-space: nowrap; width: '.$percent[$name].'%;">'."<i>$name: $count[$name] ($percent[$name]%)</i></td>";
498 <table class="progress">
500 <tr><?php echo $graph; ?></tr>
503 <table class="progress_legend">
504 <tr><?php echo $legend ?></tr>
510 if ($set=='custom') {
511 $set .= '&_assigned_to='.$_assigned_to.'&_status='.$_status.'&_sort_col='.$_sort_col.'&_sort_ord='.$_sort_ord;
512 if (array_key_exists($ath->getCustomStatusField(),$_extra_fields)) {
513 $set .= '&extra_fields['.$ath->getCustomStatusField().']='.$_extra_fields[$ath->getCustomStatusField()];
518 $IS_ADMIN = forge_check_perm ('tracker', $ath->getID(), 'manager') ;
522 <form name="artifactList" action="'. getStringFromServer('PHP_SELF') .'?group_id='.$group_id.'&atid='.$ath->getID().'" method="post">
523 <input type="hidden" name="form_key" value="'.form_generate_key().'" />
524 <input type="hidden" name="func" value="massupdate" />';
527 $browse_fields = explode(',', "id,".$ath->getBrowseList());
529 foreach ($browse_fields as $f) {
531 if (intval($f) > 0) {
532 $title = $ath->getExtraFieldName($f);
539 $title=_('Description');
540 if ($f == 'open_date')
541 $title=_('Open Date');
542 if ($f == 'close_date')
543 $title=_('Close Date');
544 if ($f == 'status_id')
546 if ($f == 'priority')
547 $title=_('Priority');
548 if ($f == 'assigned_to')
549 $title=_('Assigned to');
550 if ($f == 'submitted_by')
551 $title=_('Submitted by');
552 if ($f == 'related_tasks')
553 $title=_('Related tasks');
554 if ($f == 'last_modified_date')
555 $title=_('Last Modified Date');
557 $title_arr[] = $title;
561 echo $GLOBALS['HTML']->listTableTop ($title_arr);
564 $then=(time()-$ath->getDuePeriod());
566 for ($i=$start; $i<$max; $i++) {
567 $extra_data = $art_arr[$i]->getExtraFieldDataText();
569 <tr '. $HTML->boxGetAltRowStyle($i) . '>';
570 foreach ($browse_fields as $f) {
572 echo '<td style="white-space: nowrap;">'.
573 ($IS_ADMIN?'<input type="checkbox" name="artifact_id_list[]" value="'.
574 $art_arr[$i]->getID() .'" /> ':'').
575 '<a href="'.getStringFromServer('PHP_SELF').'?func=detail&aid='.
576 $art_arr[$i]->getID() .
577 '&group_id='. $group_id .'&atid='.
578 $ath->getID().'">'.$art_arr[$i]->getID() .
580 } else if ($f == 'summary') {
581 echo '<td><a href="'.getStringFromServer('PHP_SELF').'?func=detail&aid='.
582 $art_arr[$i]->getID() .
583 '&group_id='. $group_id .'&atid='.
585 $art_arr[$i]->getSummary().
587 } else if ($f == 'open_date') {
588 echo '<td>'. (($set != 'closed' && $art_arr[$i]->getOpenDate() < $then)?'* ':' ') .
589 date(_('Y-m-d H:i'),$art_arr[$i]->getOpenDate()) .'</td>';
590 } else if ($f == 'status_id') {
591 echo '<td>'. $art_arr[$i]->getStatusName() .'</td>';
592 } else if ($f == 'priority') {
593 echo '<td class="priority'.$art_arr[$i]->getPriority() .'">'. $art_arr[$i]->getPriority() .'</td>';
594 } else if ($f == 'assigned_to') {
595 echo '<td>'. $art_arr[$i]->getAssignedRealName() .'</td>';
596 } else if ($f == 'submitted_by') {
597 echo '<td>'. $art_arr[$i]->getSubmittedRealName() .'</td>';
598 } else if ($f == 'close_date') {
599 echo '<td>'. ($art_arr[$i]->getCloseDate() ?
600 date(_('Y-m-d H:i'),$art_arr[$i]->getCloseDate()) :' ') .'</td>';
601 } else if ($f == 'details') {
602 echo '<td>'. $art_arr[$i]->getDetails() .'</td>';
603 } else if ($f == 'related_tasks') {
605 $tasks_res = $art_arr[$i]->getRelatedTasks();
607 while ($rest = db_fetch_array($tasks_res)) {
608 $link = '/pm/task.php?func=detailtask&project_task_id='.$rest['project_task_id'].
609 '&group_id='.$group_id.'&group_project_id='.$rest['group_project_id'];
610 $title = '[T'.$rest['project_task_id'].']';
611 if ($rest['status_id'] == 2) {
612 $title = '<strike>'.$title.'</strike>';
614 print $s.'<a href="'.$link.'" title="'.util_html_secure($rest['summary']).'">'.$title.'</a>';
618 } else if ($f == 'last_modified_date') {
619 echo '<td>'. ($art_arr[$i]->getLastModifiedDate() ?
620 date(_('Y-m-d H:i'),$art_arr[$i]->getLastModifiedDate()) :' ') .'</td>';
621 } else if (intval($f) > 0) {
622 // Now display extra-fields (fields are numbers).
623 $value = $extra_data[$f]['value'];
624 if ($extra_data[$f]['type'] == 9) {
625 $value = preg_replace('/\b(\d+)\b/e', "_artifactid2url('\\1')", $value);
626 } else if ($extra_data[$f]['type'] == 7) {
627 if ($art_arr[$i]->getStatusID() == 2) {
628 $value = '<strike>'.$value.'</strike>';
632 echo '<td>' . $value .'</td>';
634 // Display ? for unknown values.
642 echo $GLOBALS['HTML']->listTableBottom();
644 $pages = $art_cnt / $paging;
645 $currentpage = intval($start / $paging);
648 $skipped_pages=false;
649 for ($j=0; $j<$pages; $j++) {
651 if ((($j > 4) && ($j < ($currentpage-5))) || (($j > ($currentpage+5)) && ($j < ($pages-5)))) {
652 if (!$skipped_pages) {
658 $skipped_pages=false;
661 if ($j * $paging == $start) {
662 echo '<strong>'.($j+1).'</strong> ';
664 echo '<a href="'.getStringFromServer('PHP_SELF')."?func=browse&group_id=".$group_id.'&atid='.$ath->getID().'&set='. $set.'&start='.($j*$paging).'"><strong>'.($j+1).'</strong></a> ';
673 echo '<script language="JavaScript" type="text/javascript">/* <![CDATA[ */
674 function checkAll(val) {
675 al=document.artifactList;
676 len = al.elements.length;
678 for( i=0 ; i<len ; i++) {
679 if (al.elements[i].name==\'artifact_id_list[]\') {
680 al.elements[i].checked=val;
686 <table width="100%" border="0" id="admin_mass_update">
689 <a href="javascript:checkAll(1)">'._('Check all').'</a>
691 <a href="javascript:checkAll(0)">'._('Clear all').'</a>
693 <div class="important">'._('<strong>Admin:</strong> If you wish to apply changes to all items selected above, use these controls to change their properties and click once on "Mass Update".').'</div>
697 // build custom fields
699 $ef = $ath->getExtraFields(array(ARTIFACT_EXTRAFIELD_FILTER_INT));
700 $keys=array_keys($ef);
703 for ($i=0; $i<count($keys); $i++) {
704 if (($ef[$keys[$i]]['field_type']==ARTIFACT_EXTRAFIELDTYPE_CHECKBOX) || ($ef[$keys[$i]]['field_type']==ARTIFACT_EXTRAFIELDTYPE_MULTISELECT)) {
705 $sel[$keys[$i]]=array('100');
707 $sel[$keys[$i]]='100';
710 $ath->renderExtraFields($sel,true,_('No Change'),false,'',array(ARTIFACT_EXTRAFIELD_FILTER_INT),true);
712 <td><strong>'._('Priority').':</strong><br />';
713 echo build_priority_select_box ('priority', '100', true);
720 <td><strong>'._('Assigned to').':</strong><br />'.
721 $ath->technicianBox ('assigned_to','100.1',true,_('Nobody'),'100.1',_('No Change')) .'</td>
723 if (!$ath->usesCustomStatuses()) {
724 echo '<strong>'._('State').':</strong>
725 <br />'. $ath->statusBox ('status_id','xzxz',true,_('No Change'));
730 <tr><td colspan="2"><strong>'._('Canned Response').':</strong><br />'.
731 $ath->cannedResponseBox ('canned_response') .'</td></tr>
733 <tr><td colspan="3" align="center"><input type="submit" name="submit" value="'._('Mass update').'" /></td></tr>
738 printf(_('* Denotes requests > %1$s Days Old'), ($ath->getDuePeriod()/86400));
740 if (in_array('priority', $browse_fields)) {
741 show_priority_colors_key();
744 echo '<p class="warning_msg">'._('No items found').'</p>';
748 $ath->footer(array());
752 // c-file-style: "bsd"