Merge branch 'develop' of projects.ceondo.com:indefero into feature.scilab
This commit is contained in:
commit
52383edfd0
1
AUTHORS
1
AUTHORS
@ -33,6 +33,7 @@ Much appreciated contributors (in alphabetical order):
|
|||||||
Samuel Suther <info@suther.de> - German translation
|
Samuel Suther <info@suther.de> - German translation
|
||||||
Sindre R. Myren <sindrero@stud.ntnu.no>
|
Sindre R. Myren <sindrero@stud.ntnu.no>
|
||||||
Stewart Platt <stew@futurete.ch>
|
Stewart Platt <stew@futurete.ch>
|
||||||
|
Stéphane Baron <sbaron>
|
||||||
Thomas Keller <me@thomaskeller.biz> - Monotone support
|
Thomas Keller <me@thomaskeller.biz> - Monotone support
|
||||||
Vladimir Solomatin <slash>
|
Vladimir Solomatin <slash>
|
||||||
William Martin <william.martin@lcpc.fr>
|
William Martin <william.martin@lcpc.fr>
|
||||||
|
10
NEWS.mdtext
10
NEWS.mdtext
@ -23,12 +23,19 @@ or newer to properly run this version of Indefero!
|
|||||||
updated downloads for a specific project, similar to the available post-commit web hook
|
updated downloads for a specific project, similar to the available post-commit web hook
|
||||||
- Indefero's issue tracker can now bi-directionally link issues with variable, configurable
|
- Indefero's issue tracker can now bi-directionally link issues with variable, configurable
|
||||||
terms, such as "is related to", "is blocked by" or "is duplicated by" (issue 638)
|
terms, such as "is related to", "is blocked by" or "is duplicated by" (issue 638)
|
||||||
|
- When you search for issues, the results can further be refined by issue state (open or closed)
|
||||||
|
and label (partially implements issue 548)
|
||||||
- Mercurial source views now show parent revisions (if any) and detailed change information
|
- Mercurial source views now show parent revisions (if any) and detailed change information
|
||||||
- Subversion source views now show detailed change information (issue 622)
|
- Subversion source views now show detailed change information (issue 622)
|
||||||
- File download URLs now contain the file name rather than the upload id; old links still work though (issues 559 and 686)
|
- File download URLs now contain the file name rather than the upload id; old links still work though (issues 559 and 686)
|
||||||
- Display monotone file and directory attributes in the tree and file view
|
- Display monotone file and directory attributes in the tree and file view
|
||||||
(needs a monotone with an interface version of 13.1 or newer)
|
(needs a monotone with an interface version of 13.1 or newer)
|
||||||
- The context area is now kept in view when a page scrolls down several pages
|
- The context area is now kept in view when a page scrolls down several pages
|
||||||
|
- Add a summary section to the issue tracker with statistics about open/close issues,
|
||||||
|
tags of open issue, and count of open tickets for each owner.
|
||||||
|
- Improved home page with an customizable icon for each project.
|
||||||
|
- The download section provide MD5 for each files.
|
||||||
|
- Wiki page have now a css for printer output (issue 713)
|
||||||
|
|
||||||
## Bugfixes
|
## Bugfixes
|
||||||
|
|
||||||
@ -56,6 +63,9 @@ or newer to properly run this version of Indefero!
|
|||||||
as we have no information what the author string is actually encoded in
|
as we have no information what the author string is actually encoded in
|
||||||
- Indefero no longer displays an empty parents paragraph in the commit view for root revisions of
|
- Indefero no longer displays an empty parents paragraph in the commit view for root revisions of
|
||||||
a git repository
|
a git repository
|
||||||
|
- Indefero now only shows the tags of the closed and not the open issues in the closed issues list
|
||||||
|
- Avatar URL generation use correctly the configuration (issue 732)
|
||||||
|
- Git cron job doesn't erase anymore manually added keys (issue 247)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ class IDF_Middleware
|
|||||||
'showuser' => 'IDF_Template_ShowUser',
|
'showuser' => 'IDF_Template_ShowUser',
|
||||||
'ashowuser' => 'IDF_Template_AssignShowUser',
|
'ashowuser' => 'IDF_Template_AssignShowUser',
|
||||||
'appversion' => 'IDF_Template_AppVersion',
|
'appversion' => 'IDF_Template_AppVersion',
|
||||||
|
'upload' => 'IDF_Template_Tag_UploadUrl',
|
||||||
));
|
));
|
||||||
$params['modifiers'] = array_merge($params['modifiers'],
|
$params['modifiers'] = array_merge($params['modifiers'],
|
||||||
array(
|
array(
|
||||||
|
@ -178,9 +178,10 @@ GROUP BY uid";
|
|||||||
*
|
*
|
||||||
* @param string Status ('open'), 'closed'
|
* @param string Status ('open'), 'closed'
|
||||||
* @param IDF_Tag Subfilter with a label (null)
|
* @param IDF_Tag Subfilter with a label (null)
|
||||||
|
* @param array Restrict further to a list of ids
|
||||||
* @return int Count
|
* @return int Count
|
||||||
*/
|
*/
|
||||||
public function getIssueCountByStatus($status='open', $label=null)
|
public function getIssueCountByStatus($status='open', $label=null, $ids=array())
|
||||||
{
|
{
|
||||||
switch ($status) {
|
switch ($status) {
|
||||||
case 'open':
|
case 'open':
|
||||||
@ -203,12 +204,48 @@ GROUP BY uid";
|
|||||||
$sql2 = new Pluf_SQL('idf_tag_id=%s', array($label->id));
|
$sql2 = new Pluf_SQL('idf_tag_id=%s', array($label->id));
|
||||||
$sql->SAnd($sql2);
|
$sql->SAnd($sql2);
|
||||||
}
|
}
|
||||||
|
if (count($ids) > 0) {
|
||||||
|
$sql2 = new Pluf_SQL(sprintf('id IN (%s)', implode(', ', $ids)));
|
||||||
|
$sql->SAnd($sql2);
|
||||||
|
}
|
||||||
$params = array('filter' => $sql->gen());
|
$params = array('filter' => $sql->gen());
|
||||||
if (!is_null($label)) { $params['view'] = 'join_tags'; }
|
if (!is_null($label)) { $params['view'] = 'join_tags'; }
|
||||||
$gissue = new IDF_Issue();
|
$gissue = new IDF_Issue();
|
||||||
return $gissue->getCount($params);
|
return $gissue->getCount($params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tags for a specific list of issues.
|
||||||
|
*
|
||||||
|
* @param string Status ('open') or 'closed'
|
||||||
|
* @param array A list of issue ids
|
||||||
|
* @return array An array of tag objects
|
||||||
|
*/
|
||||||
|
public function getTagsByIssues($issue_ids=array())
|
||||||
|
{
|
||||||
|
// make the below query always a valid one
|
||||||
|
if (count($issue_ids) == 0) $issue_ids[] = 0;
|
||||||
|
|
||||||
|
$assocTable = $this->_con->pfx.'idf_issue_idf_tag_assoc';
|
||||||
|
$query = sprintf(
|
||||||
|
'SELECT DISTINCT idf_tag_id FROM %s '.
|
||||||
|
'WHERE idf_issue_id IN (%s) '.
|
||||||
|
'GROUP BY idf_tag_id',
|
||||||
|
$assocTable, implode(',', $issue_ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
$db = Pluf::db();
|
||||||
|
$dbData = $db->select($query);
|
||||||
|
$ids = array(0);
|
||||||
|
foreach ($dbData as $data) {
|
||||||
|
$ids[] = $data['idf_tag_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = new Pluf_SQL(sprintf('id IN (%s)', implode(', ', $ids)));
|
||||||
|
$model = new IDF_Tag();
|
||||||
|
return $model->getList(array('filter' => $sql->gen()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the open/closed tag ids as they are often used when doing
|
* Get the open/closed tag ids as they are often used when doing
|
||||||
* listings.
|
* listings.
|
||||||
@ -415,7 +452,11 @@ GROUP BY uid";
|
|||||||
foreach ($this->_con->select($sql) as $idc) {
|
foreach ($this->_con->select($sql) as $idc) {
|
||||||
$tag = new IDF_Tag($idc['id']);
|
$tag = new IDF_Tag($idc['id']);
|
||||||
$tag->nb_use = $idc['nb_use'];
|
$tag->nb_use = $idc['nb_use'];
|
||||||
$tags[] = $tag;
|
// group by class
|
||||||
|
if (!array_key_exists($tag->class, $tags)) {
|
||||||
|
$tags[$tag->class] = array();
|
||||||
|
}
|
||||||
|
$tags[$tag->class][] = $tag;
|
||||||
}
|
}
|
||||||
return new Pluf_Template_ContextVars($tags);
|
return new Pluf_Template_ContextVars($tags);
|
||||||
}
|
}
|
||||||
|
35
src/IDF/Template/Tag/UploadUrl.php
Normal file
35
src/IDF/Template/Tag/UploadUrl.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2011 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
class IDF_Template_Tag_UploadUrl extends Pluf_Template_Tag
|
||||||
|
{
|
||||||
|
function start($file='')
|
||||||
|
{
|
||||||
|
echo IDF_Template_Tag_UploadUrl::url($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function url($file='')
|
||||||
|
{
|
||||||
|
return Pluf::f('url_upload', Pluf_Template_Tag_MediaUrl::url() . '/upload') . $file;
|
||||||
|
}
|
||||||
|
}
|
@ -319,13 +319,11 @@ class IDF_Views_Download
|
|||||||
$pag->no_results_text = __('No downloads were found.');
|
$pag->no_results_text = __('No downloads were found.');
|
||||||
$pag->sort_order = array('creation_dtime', 'DESC');
|
$pag->sort_order = array('creation_dtime', 'DESC');
|
||||||
$pag->setFromRequest($request);
|
$pag->setFromRequest($request);
|
||||||
$tags = $prj->getTagCloud('downloads');
|
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/downloads/index.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/downloads/index.html',
|
||||||
array(
|
array(
|
||||||
'page_title' => $title,
|
'page_title' => $title,
|
||||||
'label' => $tag,
|
'label' => $tag,
|
||||||
'downloads' => $pag,
|
'downloads' => $pag,
|
||||||
'tags' => $tags,
|
|
||||||
'dlabel' => $dtag,
|
'dlabel' => $dtag,
|
||||||
),
|
),
|
||||||
$request);
|
$request);
|
||||||
|
@ -71,7 +71,9 @@ class IDF_Views_Issue
|
|||||||
'page_title' => $title,
|
'page_title' => $title,
|
||||||
'open' => $open,
|
'open' => $open,
|
||||||
'closed' => $closed,
|
'closed' => $closed,
|
||||||
'issues' => $pag);
|
'issues' => $pag,
|
||||||
|
'cloud' => 'issues',
|
||||||
|
);
|
||||||
if ($api) return $params;
|
if ($api) return $params;
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/issues/index.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/issues/index.html',
|
||||||
$params, $request);
|
$params, $request);
|
||||||
@ -88,7 +90,7 @@ class IDF_Views_Issue
|
|||||||
$ownerStatistics = array();
|
$ownerStatistics = array();
|
||||||
$status = array();
|
$status = array();
|
||||||
$isTrackerEmpty = false;
|
$isTrackerEmpty = false;
|
||||||
|
|
||||||
$prj = $request->project;
|
$prj = $request->project;
|
||||||
$opened = $prj->getIssueCountByStatus('open');
|
$opened = $prj->getIssueCountByStatus('open');
|
||||||
$closed = $prj->getIssueCountByStatus('closed');
|
$closed = $prj->getIssueCountByStatus('closed');
|
||||||
@ -102,24 +104,28 @@ class IDF_Views_Issue
|
|||||||
$status['Open'] = array($opened, (int)(100 * $opened / ($opened + $closed)));
|
$status['Open'] = array($opened, (int)(100 * $opened / ($opened + $closed)));
|
||||||
$status['Closed'] = array($closed, (int)(100 * $closed / ($opened + $closed)));
|
$status['Closed'] = array($closed, (int)(100 * $closed / ($opened + $closed)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($opened > 0) {
|
if ($opened > 0) {
|
||||||
// Issue owner statistics
|
// Issue owner statistics
|
||||||
$owners = $prj->getIssueCountByOwner('open');
|
$owners = $prj->getIssueCountByOwner('open');
|
||||||
foreach ($owners as $user => $nb) {
|
foreach ($owners as $user => $nb) {
|
||||||
if ($user === '') {
|
if ($user === '') {
|
||||||
$key = __('Not assigned');
|
$key = __('Not assigned');
|
||||||
|
$login = null;
|
||||||
} else {
|
} else {
|
||||||
$obj = Pluf::factory('Pluf_User')->getOne(array('filter'=>'id='.$user));
|
$obj = Pluf::factory('Pluf_User')->getOne(array('filter'=>'id='.$user));
|
||||||
$key = $obj->first_name . ' ' . $obj->last_name;
|
$key = $obj->first_name . ' ' . $obj->last_name;
|
||||||
|
$login = $obj->login;
|
||||||
}
|
}
|
||||||
$ownerStatistics[$key] = array($nb, (int)(100 * $nb / $opened));
|
$ownerStatistics[$key] = array($nb, (int)(100 * $nb / $opened), $login);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue class tag statistics
|
// Issue class tag statistics
|
||||||
$tags = $prj->getTagCloud();
|
$grouped_tags = $prj->getTagCloud();
|
||||||
foreach ($tags as $t) {
|
foreach ($grouped_tags as $class => $tags) {
|
||||||
$tagStatistics[$t->class][$t->name] = array($t->nb_use, $t->id);
|
foreach ($tags as $tag) {
|
||||||
|
$tagStatistics[$class][$tag->name] = array($tag->nb_use, $tag->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach($tagStatistics as $k => $v) {
|
foreach($tagStatistics as $k => $v) {
|
||||||
$nbIssueInClass = 0;
|
$nbIssueInClass = 0;
|
||||||
@ -130,15 +136,15 @@ class IDF_Views_Issue
|
|||||||
$tagStatistics[$k][$kk] = array($vv[0], (int)(100 * $vv[0] / $nbIssueInClass), $vv[1]);
|
$tagStatistics[$k][$kk] = array($vv[0], (int)(100 * $vv[0] / $nbIssueInClass), $vv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort
|
// Sort
|
||||||
krsort($tagStatistics);
|
krsort($tagStatistics);
|
||||||
arsort($ownerStatistics);
|
arsort($ownerStatistics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$title = sprintf(__('Summary of tracked issues in %s.'), (string) $prj);
|
$title = sprintf(__('Summary of tracked issues in %s.'), (string) $prj);
|
||||||
|
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/issues/summary.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/issues/summary.html',
|
||||||
array('page_title' => $title,
|
array('page_title' => $title,
|
||||||
'trackerEmpty' => $isTrackerEmpty,
|
'trackerEmpty' => $isTrackerEmpty,
|
||||||
@ -149,7 +155,7 @@ class IDF_Views_Issue
|
|||||||
),
|
),
|
||||||
$request);
|
$request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View the issues watch list of a given user.
|
* View the issues watch list of a given user.
|
||||||
* Limited to a specified project
|
* Limited to a specified project
|
||||||
@ -313,42 +319,55 @@ class IDF_Views_Issue
|
|||||||
*
|
*
|
||||||
* Only open issues are shown.
|
* Only open issues are shown.
|
||||||
*/
|
*/
|
||||||
public $myIssues_precond = array('IDF_Precondition::accessIssues',
|
public $userIssues_precond = array('IDF_Precondition::accessIssues');
|
||||||
'Pluf_Precondition::loginRequired');
|
public function userIssues($request, $match)
|
||||||
public function myIssues($request, $match)
|
|
||||||
{
|
{
|
||||||
$prj = $request->project;
|
$prj = $request->project;
|
||||||
|
|
||||||
|
$sql = new Pluf_SQL('login=%s', array($match[2]));
|
||||||
|
$user = Pluf::factory('Pluf_User')->getOne(array('filter' => $sql->gen()));
|
||||||
|
if ($user === null) {
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
|
||||||
|
array($prj->shortname));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
}
|
||||||
|
|
||||||
$otags = $prj->getTagIdsByStatus('open');
|
$otags = $prj->getTagIdsByStatus('open');
|
||||||
$ctags = $prj->getTagIdsByStatus('closed');
|
$ctags = $prj->getTagIdsByStatus('closed');
|
||||||
if (count($otags) == 0) $otags[] = 0;
|
if (count($otags) == 0) $otags[] = 0;
|
||||||
if (count($ctags) == 0) $ctags[] = 0;
|
if (count($ctags) == 0) $ctags[] = 0;
|
||||||
switch ($match[2]) {
|
switch ($match[3]) {
|
||||||
case 'submit':
|
case 'submit':
|
||||||
$title = sprintf(__('My Submitted %s Issues'), (string) $prj);
|
$titleFormat = __('%s %s Submitted %s Issues');
|
||||||
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||||
break;
|
break;
|
||||||
case 'submitclosed':
|
case 'submitclosed':
|
||||||
$title = sprintf(__('My Closed Submitted %s Issues'), (string) $prj);
|
$titleFormat = __('%s %s Closed Submitted %s Issues');
|
||||||
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||||
break;
|
break;
|
||||||
case 'ownerclosed':
|
case 'ownerclosed':
|
||||||
$title = sprintf(__('My Closed Working %s Issues'), (string) $prj);
|
$titleFormat = __('%s %s Closed Working %s Issues');
|
||||||
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$title = sprintf(__('My Working %s Issues'), (string) $prj);
|
$titleFormat = __('%s %s Working %s Issues');
|
||||||
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
$title = sprintf($titleFormat,
|
||||||
|
$user->first_name,
|
||||||
|
$user->last_name,
|
||||||
|
(string) $prj);
|
||||||
|
|
||||||
// Get stats about the issues
|
// Get stats about the issues
|
||||||
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||||
$nb_submit = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
$nb_submit = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||||
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
|
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $user->id));
|
||||||
$nb_owner = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
$nb_owner = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||||
// Closed issues
|
// Closed issues
|
||||||
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||||
$nb_submit_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
$nb_submit_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||||
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $request->user->id));
|
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $ctags).')', array($prj->id, $user->id));
|
||||||
$nb_owner_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
$nb_owner_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
|
||||||
|
|
||||||
// Paginator to paginate the issues
|
// Paginator to paginate the issues
|
||||||
@ -359,7 +378,7 @@ class IDF_Views_Issue
|
|||||||
'current_user' => $request->user);
|
'current_user' => $request->user);
|
||||||
$pag->summary = __('This table shows the open issues.');
|
$pag->summary = __('This table shows the open issues.');
|
||||||
$pag->forced_where = $f_sql;
|
$pag->forced_where = $f_sql;
|
||||||
$pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2]));
|
$pag->action = array('IDF_Views_Issue::userIssues', array($prj->shortname, $match[2]));
|
||||||
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
|
||||||
$pag->sort_reverse_order = array('modif_dtime');
|
$pag->sort_reverse_order = array('modif_dtime');
|
||||||
$pag->sort_link_title = true;
|
$pag->sort_link_title = true;
|
||||||
@ -374,9 +393,10 @@ class IDF_Views_Issue
|
|||||||
$pag->items_per_page = 10;
|
$pag->items_per_page = 10;
|
||||||
$pag->no_results_text = __('No issues were found.');
|
$pag->no_results_text = __('No issues were found.');
|
||||||
$pag->setFromRequest($request);
|
$pag->setFromRequest($request);
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/issues/my-issues.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/issues/userIssues.html',
|
||||||
array('project' => $prj,
|
array('project' => $prj,
|
||||||
'page_title' => $title,
|
'page_title' => $title,
|
||||||
|
'login' => $user->login,
|
||||||
'nb_submit' => $nb_submit,
|
'nb_submit' => $nb_submit,
|
||||||
'nb_owner' => $nb_owner,
|
'nb_owner' => $nb_owner,
|
||||||
'nb_submit_closed' => $nb_submit_closed,
|
'nb_submit_closed' => $nb_submit_closed,
|
||||||
@ -429,45 +449,142 @@ class IDF_Views_Issue
|
|||||||
|
|
||||||
public $search_precond = array('IDF_Precondition::accessIssues');
|
public $search_precond = array('IDF_Precondition::accessIssues');
|
||||||
public function search($request, $match)
|
public function search($request, $match)
|
||||||
|
{
|
||||||
|
$query = !isset($request->REQUEST['q']) ? '' : $request->REQUEST['q'];
|
||||||
|
return $this->doSearch($request, $query, 'open');
|
||||||
|
}
|
||||||
|
|
||||||
|
public $searchStatus_precond = array('IDF_Precondition::accessIssues');
|
||||||
|
public function searchStatus($request, $match)
|
||||||
|
{
|
||||||
|
$query = !isset($request->REQUEST['q']) ? '' : $request->REQUEST['q'];
|
||||||
|
$status = in_array($match[2], array('open', 'closed')) ? $match[2] : 'open';
|
||||||
|
return $this->doSearch($request, $query, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public $searchLabel_precond = array('IDF_Precondition::accessIssues');
|
||||||
|
public function searchLabel($request, $match)
|
||||||
|
{
|
||||||
|
$query = !isset($request->REQUEST['q']) ? '' : $request->REQUEST['q'];
|
||||||
|
$tag_id = intval($match[2]);
|
||||||
|
$status = in_array($match[3], array('open', 'closed')) ? $match[3] : 'open';
|
||||||
|
return $this->doSearch($request, $query, $status, $tag_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function doSearch($request, $query, $status, $tag_id=null)
|
||||||
{
|
{
|
||||||
$prj = $request->project;
|
$prj = $request->project;
|
||||||
if (!isset($request->REQUEST['q']) or trim($request->REQUEST['q']) == '') {
|
if (trim($query) == '') {
|
||||||
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index', array($prj->shortname));
|
||||||
array($prj->shortname));
|
|
||||||
return new Pluf_HTTP_Response_Redirect($url);
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
}
|
}
|
||||||
$q = $request->REQUEST['q'];
|
|
||||||
$title = sprintf(__('Search Issues - %s'), $q);
|
$tag = null;
|
||||||
$issues = new Pluf_Search_ResultSet(IDF_Search::mySearch($q, $prj, 'IDF_Issue'));
|
if ($tag_id !== null) {
|
||||||
if (count($issues) > 100) {
|
$tag = Pluf_Shortcuts_GetObjectOr404('IDF_Tag', $tag_id);
|
||||||
// no more than 100 results as we do not care
|
|
||||||
$issues->results = array_slice($issues->results, 0, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$title = sprintf(__('Search issues - %s'), $query);
|
||||||
|
if ($status === 'closed') {
|
||||||
|
$title = sprintf(__('Search closed issues - %s'), $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// using Plufs ResultSet implementation here is inefficient, because
|
||||||
|
// it makes a SELECT for each item and does not allow for further
|
||||||
|
// filtering neither, so we just return the ids and filter by them
|
||||||
|
// and other things in the next round
|
||||||
|
$results = IDF_Search::mySearch($query, $prj, 'IDF_Issue');
|
||||||
|
|
||||||
|
$issue_ids = array(0);
|
||||||
|
foreach ($results as $result) {
|
||||||
|
$issue_ids[] = $result['model_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$otags = $prj->getTagIdsByStatus($status);
|
||||||
|
if (count($otags) == 0) $otags[] = 0;
|
||||||
|
$sql = new Pluf_SQL(
|
||||||
|
'id IN ('.implode(',', $issue_ids).') '.
|
||||||
|
'AND status IN ('.implode(', ', $otags).') '.
|
||||||
|
($tag_id !== null ? 'AND idf_tag_id='.$tag_id.' ' : '')
|
||||||
|
);
|
||||||
|
$model = new IDF_Issue();
|
||||||
|
$issues = $model->getList(array('filter' => $sql->gen(), 'view' => 'join_tags'));
|
||||||
|
|
||||||
|
// we unfortunately loose the original sort order,
|
||||||
|
// so we manually have to apply it here again
|
||||||
|
$sorted_issues = new ArrayObject();
|
||||||
|
$filtered_issue_ids = array(0);
|
||||||
|
foreach ($issue_ids as $issue_id) {
|
||||||
|
foreach ($issues as $issue) {
|
||||||
|
if ($issue->id != $issue_id)
|
||||||
|
continue;
|
||||||
|
if (array_key_exists($issue_id, $sorted_issues))
|
||||||
|
continue;
|
||||||
|
$sorted_issues[$issue_id] = $issue;
|
||||||
|
$filtered_issue_ids[] = $issue_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$pag = new Pluf_Paginator();
|
$pag = new Pluf_Paginator();
|
||||||
$pag->items = $issues;
|
|
||||||
$pag->class = 'recent-issues';
|
$pag->class = 'recent-issues';
|
||||||
$pag->item_extra_props = array('project_m' => $prj,
|
$pag->items = $sorted_issues;
|
||||||
'shortname' => $prj->shortname,
|
$pag->item_extra_props = array(
|
||||||
'current_user' => $request->user);
|
'project_m' => $prj,
|
||||||
|
'shortname' => $prj->shortname,
|
||||||
|
'current_user' => $request->user
|
||||||
|
);
|
||||||
$pag->summary = __('This table shows the found issues.');
|
$pag->summary = __('This table shows the found issues.');
|
||||||
$pag->action = array('IDF_Views_Issue::search', array($prj->shortname), array('q'=> $q));
|
|
||||||
$pag->extra_classes = array('a-c', '', 'a-c', '');
|
$pag->extra_classes = array('a-c', '', 'a-c', '');
|
||||||
$list_display = array(
|
$pag->configure(array(
|
||||||
'id' => __('Id'),
|
'id' => __('Id'),
|
||||||
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
|
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
|
||||||
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
|
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
|
||||||
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
|
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
|
||||||
);
|
));
|
||||||
$pag->configure($list_display);
|
// disable paginating
|
||||||
$pag->items_per_page = 100;
|
$pag->items_per_page = PHP_INT_MAX;
|
||||||
$pag->no_results_text = __('No issues were found.');
|
$pag->no_results_text = __('No issues were found.');
|
||||||
$pag->setFromRequest($request);
|
$pag->setFromRequest($request);
|
||||||
$params = array('page_title' => $title,
|
|
||||||
'issues' => $pag,
|
|
||||||
'q' => $q,
|
|
||||||
);
|
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/issues/search.html', $params, $request);
|
|
||||||
|
|
||||||
|
if ($tag_id === null) {
|
||||||
|
$pag->action = array('IDF_Views_Issue::searchStatus',
|
||||||
|
array($prj->shortname, $status),
|
||||||
|
array('q'=> $query),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$pag->action = array('IDF_Views_Issue::searchLabel',
|
||||||
|
array($prj->shortname, $tag_id, $status),
|
||||||
|
array('q'=> $query),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get stats about the issues
|
||||||
|
$open = $prj->getIssueCountByStatus('open', $tag, $issue_ids);
|
||||||
|
$closed = $prj->getIssueCountByStatus('closed', $tag, $issue_ids);
|
||||||
|
|
||||||
|
// query the available tags for this search result
|
||||||
|
$all_tags = $prj->getTagsByIssues($filtered_issue_ids);
|
||||||
|
$grouped_tags = array();
|
||||||
|
foreach ($all_tags as $atag) {
|
||||||
|
// group by class
|
||||||
|
if (!array_key_exists($atag->class, $grouped_tags)) {
|
||||||
|
$grouped_tags[$atag->class] = array();
|
||||||
|
}
|
||||||
|
$grouped_tags[$atag->class][] = $atag;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
'page_title' => $title,
|
||||||
|
'issues' => $pag,
|
||||||
|
'query' => $query,
|
||||||
|
'status' => $status,
|
||||||
|
'open' => $open,
|
||||||
|
'closed' => $closed,
|
||||||
|
'tag' => $tag,
|
||||||
|
'all_tags' => $grouped_tags,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('idf/issues/search.html', $params, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public $view_precond = array('IDF_Precondition::accessIssues');
|
public $view_precond = array('IDF_Precondition::accessIssues');
|
||||||
@ -615,6 +732,13 @@ class IDF_Views_Issue
|
|||||||
{
|
{
|
||||||
$prj = $request->project;
|
$prj = $request->project;
|
||||||
$status = $match[2];
|
$status = $match[2];
|
||||||
|
|
||||||
|
if (mb_strtolower($status) == 'open') {
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
|
||||||
|
array($prj->shortname));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
}
|
||||||
|
|
||||||
$title = sprintf(__('%s Closed Issues'), (string) $prj);
|
$title = sprintf(__('%s Closed Issues'), (string) $prj);
|
||||||
// Get stats about the issues
|
// Get stats about the issues
|
||||||
$open = $prj->getIssueCountByStatus('open');
|
$open = $prj->getIssueCountByStatus('open');
|
||||||
|
@ -152,13 +152,11 @@ class IDF_Views_Wiki
|
|||||||
$pag->items_per_page = 25;
|
$pag->items_per_page = 25;
|
||||||
$pag->no_results_text = __('No documentation pages were found.');
|
$pag->no_results_text = __('No documentation pages were found.');
|
||||||
$pag->setFromRequest($request);
|
$pag->setFromRequest($request);
|
||||||
$tags = $prj->getTagCloud('wiki');
|
|
||||||
return Pluf_Shortcuts_RenderToResponse('idf/wiki/index.html',
|
return Pluf_Shortcuts_RenderToResponse('idf/wiki/index.html',
|
||||||
array(
|
array(
|
||||||
'page_title' => $title,
|
'page_title' => $title,
|
||||||
'label' => $tag,
|
'label' => $tag,
|
||||||
'pages' => $pag,
|
'pages' => $pag,
|
||||||
'tags' => $tags,
|
|
||||||
'dlabel' => $dtag,
|
'dlabel' => $dtag,
|
||||||
),
|
),
|
||||||
$request);
|
$request);
|
||||||
|
@ -117,7 +117,7 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/$#',
|
|||||||
'base' => $base,
|
'base' => $base,
|
||||||
'model' => 'IDF_Views_Issue',
|
'model' => 'IDF_Views_Issue',
|
||||||
'method' => 'index');
|
'method' => 'index');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/summary/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/summary/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'model' => 'IDF_Views_Issue',
|
'model' => 'IDF_Views_Issue',
|
||||||
@ -128,6 +128,16 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/$#',
|
|||||||
'model' => 'IDF_Views_Issue',
|
'model' => 'IDF_Views_Issue',
|
||||||
'method' => 'search');
|
'method' => 'search');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/status/(\w+)/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'model' => 'IDF_Views_Issue',
|
||||||
|
'method' => 'searchStatus');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/label/(\d+)/(\w+)/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'model' => 'IDF_Views_Issue',
|
||||||
|
'method' => 'searchLabel');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'model' => 'IDF_Views_Issue',
|
'model' => 'IDF_Views_Issue',
|
||||||
@ -153,10 +163,10 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/create/$#',
|
|||||||
'model' => 'IDF_Views_Issue',
|
'model' => 'IDF_Views_Issue',
|
||||||
'method' => 'create');
|
'method' => 'create');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/my/(\w+)/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(.*)/(\w+)/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'model' => 'IDF_Views_Issue',
|
'model' => 'IDF_Views_Issue',
|
||||||
'method' => 'myIssues');
|
'method' => 'userIssues');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
<div id="sub-tabs">
|
<div id="sub-tabs">
|
||||||
<a {if $inSummaryIssues}class="active" {/if}href="{url 'IDF_Views_Issue::summary', array($project.shortname)}">{trans 'Summary'}</a>
|
<a {if $inSummaryIssues}class="active" {/if}href="{url 'IDF_Views_Issue::summary', array($project.shortname)}">{trans 'Summary'}</a>
|
||||||
| <a {if $inOpenIssues}class="active" {/if}href="{url 'IDF_Views_Issue::index', array($project.shortname)}">{trans 'Open Issues'}</a>
|
| <a {if $inOpenIssues}class="active" {/if}href="{url 'IDF_Views_Issue::index', array($project.shortname)}">{trans 'Open Issues'}</a>
|
||||||
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}">{trans 'My Issues'}</a>
|
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'submit')}">{trans 'My Issues'}</a>
|
||||||
| <a {if $inWatchList}class="active" {/if}href="{url 'IDF_Views_Issue::watchList', array($project.shortname, 'open')}">{trans 'My watch list'}</a>{/if} |
|
| <a {if $inWatchList}class="active" {/if}href="{url 'IDF_Views_Issue::watchList', array($project.shortname, 'open')}">{trans 'My watch list'}</a>{/if} |
|
||||||
<form class="star" action="{url 'IDF_Views_Issue::search', array($project.shortname)}" method="get">
|
<form class="star" action="{url 'IDF_Views_Issue::search', array($project.shortname)}" method="get">
|
||||||
<input accesskey="4" type="text" value="{$q}" name="q" size="20" />
|
<input accesskey="4" type="text" value="{$query}" name="q" size="20" />
|
||||||
<input type="submit" name="s" value="{trans 'Search'}" />
|
<input type="submit" name="s" value="{trans 'Search'}" />
|
||||||
</form>
|
</form>
|
||||||
{if $inIssue} |
|
{if $inIssue} |
|
||||||
|
@ -8,16 +8,15 @@
|
|||||||
|
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
{block context}
|
||||||
<p><strong>{trans 'Label:'}</strong>
|
|
||||||
{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
|
|
||||||
<a href="{$url}" class="label"><strong>{$label.class}:</strong>{$label.name}</a></p>
|
|
||||||
{aurl 'open_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
|
{aurl 'open_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
|
||||||
{aurl 'closed_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'closed')}
|
{aurl 'closed_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'closed')}
|
||||||
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
|
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
|
||||||
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
|
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
|
||||||
{/blocktrans}{if $completion}
|
{/blocktrans}
|
||||||
|
<p><strong>{trans 'Label:'}</strong>
|
||||||
|
{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
|
||||||
|
<a href="{$url}" class="label"><strong>{$label.class}:</strong>{$label.name}</a></p>
|
||||||
|
{if $completion}
|
||||||
<p><strong>{trans 'Completion:'}</strong> {$completion}</p>
|
<p><strong>{trans 'Completion:'}</strong> {$completion}</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
{/block}
|
{/block}
|
||||||
|
@ -13,6 +13,5 @@
|
|||||||
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
|
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
|
||||||
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
|
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
|
||||||
{assign $cloud_url = 'IDF_Views_Issue::listLabel'}
|
{assign $cloud_url = 'IDF_Views_Issue::listLabel'}
|
||||||
{assign $cloud = 'issues'}
|
|
||||||
{include 'idf/tags-cloud.html'}
|
{include 'idf/tags-cloud.html'}
|
||||||
{/block}
|
{/block}
|
||||||
|
@ -8,5 +8,25 @@
|
|||||||
|
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
{block context}
|
||||||
<p><strong>{trans 'Found issues:'}</strong> {$issues.nb_items}</p>
|
{aurl 'open_url', 'IDF_Views_Issue::searchStatus', array($project.shortname, 'open'), array('q' => $query)}
|
||||||
|
{aurl 'closed_url', 'IDF_Views_Issue::searchStatus', array($project.shortname, 'closed'), array('q' => $query)}
|
||||||
|
{if $tag != null}
|
||||||
|
{aurl 'open_url', 'IDF_Views_Issue::searchLabel', array($project.shortname, $tag.id, 'open'), array('q' => $query)}
|
||||||
|
{aurl 'closed_url', 'IDF_Views_Issue::searchLabel', array($project.shortname, $tag.id, 'closed'), array('q' => $query)}
|
||||||
|
{/if}
|
||||||
|
{blocktrans}
|
||||||
|
<p><strong>Found open issues:</strong> <a href="{$open_url}">{$open}</a></p>
|
||||||
|
<p><strong>Found closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
|
||||||
|
{if $tag !== null}
|
||||||
|
{blocktrans}<p><strong>Label:</strong>
|
||||||
|
<a href="{$open_url}" class="label"><strong>{$tag.class}:</strong>{$tag.name}</a></p>{/blocktrans}
|
||||||
|
{else}
|
||||||
|
{* yes, this is duplicated from tags-cloud.html, but the code there cannot be easily overridden *}
|
||||||
|
<div id="tagscloud" class="smaller"><dl>{foreach $all_tags as $class => $labels}
|
||||||
|
<dt class="label">{$class}</dt>
|
||||||
|
{foreach $labels as $idx => $label}
|
||||||
|
{aurl 'url', 'IDF_Views_Issue::searchLabel', array($project.shortname, $label.id, $status), array('q'=> $query)}
|
||||||
|
<dd><a href="{$url}" class="label">{$label.name}{if $idx != count($labels) - 1},{/if}</a></dd>
|
||||||
|
{/foreach}{/foreach}</dl></p>
|
||||||
|
{/if}
|
||||||
{/block}
|
{/block}
|
||||||
|
@ -71,7 +71,12 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{foreach $ownerStatistics as $key => $value}
|
{foreach $ownerStatistics as $key => $value}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name">{$key}</td>
|
<td class="name">
|
||||||
|
{if !empty($value[2])}
|
||||||
|
{aurl 'url', 'IDF_Views_Issue::userIssues', array($project.shortname, $value[2], 'owner')}
|
||||||
|
<a href="{$url}">{$key}</a>
|
||||||
|
{else}{$key}{/if}
|
||||||
|
</td>
|
||||||
<td class="count">{$value[0]}</td>
|
<td class="count">{$value[0]}</td>
|
||||||
<td class="graph">
|
<td class="graph">
|
||||||
<table class='graph'>
|
<table class='graph'>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{extends "idf/issues/base.html"}
|
{extends "idf/issues/base.html"}
|
||||||
{block docclass}yui-t2{assign $inMyIssues = true}{/block}
|
{block docclass}yui-t2{if $user.login == $login}{assign $inMyIssues = true}{/if}{/block}
|
||||||
{block body}
|
{block body}
|
||||||
{$issues.render}
|
{$issues.render}
|
||||||
{if !$user.isAnonymous()}
|
{if !$user.isAnonymous()}
|
||||||
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
{block context}
|
||||||
{aurl 'owner_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'owner')}
|
{aurl 'owner_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'owner')}
|
||||||
{aurl 'submit_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}
|
{aurl 'submit_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'submit')}
|
||||||
{aurl 'owner_closed_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'ownerclosed')}
|
{aurl 'owner_closed_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'ownerclosed')}
|
||||||
{aurl 'submit_closed_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submitclosed')}
|
{aurl 'submit_closed_url', 'IDF_Views_Issue::userIssues', array($project.shortname, $login, 'submitclosed')}
|
||||||
<p><strong>{trans 'Submitted issues:'}</strong> <a href="{$submit_url}">{$nb_submit}</a>
|
<p><strong>{trans 'Submitted issues:'}</strong> <a href="{$submit_url}">{$nb_submit}</a>
|
||||||
{if $nb_submit_closed}<br /><span class="helptext">{blocktrans $nb_submit_closed}See the <a href="{$submit_closed_url}">{$nb_submit_closed} closed</a>.{plural}See the <a href="{$submit_closed_url}">{$nb_submit_closed} closed</a>.{/blocktrans}</span>{/if}</p>
|
{if $nb_submit_closed}<br /><span class="helptext">{blocktrans $nb_submit_closed}See the <a href="{$submit_closed_url}">{$nb_submit_closed} closed</a>.{plural}See the <a href="{$submit_closed_url}">{$nb_submit_closed} closed</a>.{/blocktrans}</span>{/if}</p>
|
||||||
{if $nb_owner > 0}
|
{if $nb_owner > 0}
|
@ -17,7 +17,7 @@
|
|||||||
{assign $submitter_data = $c.get_submitter_data()}
|
{assign $submitter_data = $c.get_submitter_data()}
|
||||||
<div class="issue-comment{if $i == 0} issue-comment-first{/if}{if $i == ($nc-1)} issue-comment-last{/if}" id="ic{$c.id}">
|
<div class="issue-comment{if $i == 0} issue-comment-first{/if}{if $i == ($nc-1)} issue-comment-last{/if}" id="ic{$c.id}">
|
||||||
{if $submitter_data.avatar != ''}
|
{if $submitter_data.avatar != ''}
|
||||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{media}/upload/avatars/{$submitter_data.avatar}" alt=" " />
|
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{upload}/avatars/{$submitter_data.avatar}" alt=" " />
|
||||||
{else}
|
{else}
|
||||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="http://www.gravatar.com/avatar/{$submitter.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="http://www.gravatar.com/avatar/{$submitter.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
{if $hasWikiAccess}{hotkey 'Shift+o', 'IDF_Views_Wiki::index', array($project.shortname)}{/if}
|
{if $hasWikiAccess}{hotkey 'Shift+o', 'IDF_Views_Wiki::index', array($project.shortname)}{/if}
|
||||||
{if $hasSourceAccess}{hotkey 'Shift+s', 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}{/if}
|
{if $hasSourceAccess}{hotkey 'Shift+s', 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}{/if}
|
||||||
{if $hasIssuesAccess and !$user.isAnonymous()}
|
{if $hasIssuesAccess and !$user.isAnonymous()}
|
||||||
{hotkey 'Shift+m', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}
|
{hotkey 'Shift+m', 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'submit')}
|
||||||
{hotkey 'Shift+w', 'IDF_Views_Issue::myIssues', array($project.shortname, 'owner')}
|
{hotkey 'Shift+w', 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'owner')}
|
||||||
{/if}{/if} //-->
|
{/if}{/if} //-->
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div id="sub-tabs">
|
<div id="sub-tabs">
|
||||||
<a {if $inOpenReviews}class="active" {/if}href="{url 'IDF_Views_Review::index', array($project.shortname)}">{trans 'Open Reviews'}</a> {*
|
<a {if $inOpenReviews}class="active" {/if}href="{url 'IDF_Views_Review::index', array($project.shortname)}">{trans 'Open Reviews'}</a> {*
|
||||||
|
|
||||||
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}">{trans 'My Issues'}</a>{/if} |
|
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a {if $inMyIssues}class="active" {/if}href="{url 'IDF_Views_Issue::userIssues', array($project.shortname, $user.login, 'submit')}">{trans 'My Issues'}</a>{/if} |
|
||||||
<form class="star" action="{url 'IDF_Views_Issue::search', array($project.shortname)}" method="get">
|
<form class="star" action="{url 'IDF_Views_Issue::search', array($project.shortname)}" method="get">
|
||||||
<input accesskey="4" type="text" value="{$q}" name="q" size="20" />
|
<input accesskey="4" type="text" value="{$q}" name="q" size="20" />
|
||||||
<input type="submit" name="s" value="{trans 'Search'}" />
|
<input type="submit" name="s" value="{trans 'Search'}" />
|
||||||
|
@ -5,17 +5,4 @@
|
|||||||
{if !$user.isAnonymous()}
|
{if !$user.isAnonymous()}
|
||||||
{aurl 'url', 'IDF_Views_Review::create', array($project.shortname)}
|
{aurl 'url', 'IDF_Views_Review::create', array($project.shortname)}
|
||||||
<p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Start Code Review'}</a></p>{/if}
|
<p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Start Code Review'}</a></p>{/if}
|
||||||
|
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
|
||||||
{*
|
|
||||||
{aurl 'open_url', 'IDF_Views_Issue::index', array($project.shortname)}
|
|
||||||
{aurl 'closed_url', 'IDF_Views_Issue::listStatus', array($project.shortname, 'closed')}
|
|
||||||
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
|
|
||||||
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
|
|
||||||
{assign $class = ''}{assign $i = 0}
|
|
||||||
<p class="smaller">{foreach $project.getTagCloud($cloud) as $label}
|
|
||||||
{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
|
|
||||||
{if $class != $label.class}{if $i != 0}<br />{/if}<strong class="label">{$label.class}:</strong> {/if}
|
|
||||||
<a href="{$url}" class="label">{$label.name}</a>,{assign $class = $label.class}{assign $i = $i + 1}{/foreach}</p>
|
|
||||||
*}{/block}
|
|
||||||
|
@ -109,7 +109,7 @@ to propose more contributions</strong>.
|
|||||||
{foreach $comments as $c}{ashowuser 'submitter', $c.get_submitter(), $request}{assign $submitter = $c.get_submitter()}{assign $submitter_data = $c.get_submitter_data()}
|
{foreach $comments as $c}{ashowuser 'submitter', $c.get_submitter(), $request}{assign $submitter = $c.get_submitter()}{assign $submitter_data = $c.get_submitter_data()}
|
||||||
<div class="issue-comment{if $i == 1} issue-comment-first{/if}{if $i == ($nc)} issue-comment-last{/if}" id="ic{$c.id}">
|
<div class="issue-comment{if $i == 1} issue-comment-first{/if}{if $i == ($nc)} issue-comment-last{/if}" id="ic{$c.id}">
|
||||||
{if $submitter_data.avatar != ''}
|
{if $submitter_data.avatar != ''}
|
||||||
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{media}/upload/avatars/{$submitter_data.avatar}" alt=" " />
|
<img style="float:right; position: relative; max-height: 60px; max-width: 60px;" src="{upload}/avatars/{$submitter_data.avatar}" alt=" " />
|
||||||
{else}
|
{else}
|
||||||
<img style="float:right; position: relative;" src="http://www.gravatar.com/avatar/{$submitter.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
<img style="float:right; position: relative;" src="http://www.gravatar.com/avatar/{$submitter.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
{assign $class = ''}{assign $i = 0}
|
<div id="tagscloud" class="smaller"><dl>{foreach $project.getTagCloud($cloud) as $class => $labels}
|
||||||
<div id="tagscloud" class="smaller"><dl>{foreach $project.getTagCloud($cloud) as $label}
|
<dt class="label">{$class}</dt>
|
||||||
|
{foreach $labels as $idx => $label}
|
||||||
{aurl 'url', $cloud_url, array($project.shortname, $label.id, 'open')}
|
{aurl 'url', $cloud_url, array($project.shortname, $label.id, 'open')}
|
||||||
{if $class != $label.class}<dt class="label">{$label.class}</dt>{assign $i = 0}{/if}
|
<dd><a href="{$url}" class="label">{$label.name}{if $idx != count($labels) - 1},{/if}</a></dd>
|
||||||
<dd><a href="{$url}" class="label">{$label.name},</a></dd>
|
{/foreach}{/foreach}</dl></p>
|
||||||
{assign $class = $label.class}
|
|
||||||
{assign $i = $i + 1}
|
|
||||||
{/foreach}</dl></p>
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<table class="form" summary="">
|
<table class="form" summary="">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="text-align: right">{if $user_data.avatar != ''}
|
<th style="text-align: right">{if $user_data.avatar != ''}
|
||||||
<img style="max-height: 60px; max-width: 60px;" src="{media}/upload/avatars/{$user_data.avatar}" alt=" " />
|
<img style="max-height: 60px; max-width: 60px;" src="{upload}/avatars/{$user_data.avatar}" alt=" " />
|
||||||
{else}
|
{else}
|
||||||
<img src="http://www.gravatar.com/avatar/{$member.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
<img src="http://www.gravatar.com/avatar/{$member.email|md5}.jpg?s=60&d={media}/idf/img/spacer.gif" alt=" " />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
{extends "idf/wiki/base.html"}
|
{extends "idf/wiki/base.html"}
|
||||||
{block extraheader}{if $oldrev}<meta name="ROBOTS" content="NOINDEX" />{/if}{/block}
|
|
||||||
|
{block extraheader}
|
||||||
|
{if $oldrev}<meta name="ROBOTS" content="NOINDEX" />{/if}
|
||||||
|
<link rel="stylesheet" type="text/css" media="print" href="{media '/idf/css/print-wiki.css'}" />
|
||||||
|
{/block}
|
||||||
|
|
||||||
{block docclass}yui-t3{assign $inView=true}{/block}
|
{block docclass}yui-t3{assign $inView=true}{/block}
|
||||||
|
|
||||||
{block body}
|
{block body}
|
||||||
|
32
www/media/idf/css/print-wiki.css
Normal file
32
www/media/idf/css/print-wiki.css
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008-2011 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#hd, #ft, #context {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yui-t3 #yui-main .yui-b {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wiki-toc {
|
||||||
|
float: none;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user