Add an sub-tab under Issue to add a summury view

feature.issue-summary
William MARTIN 2011-06-15 09:11:47 +02:00
parent 8e4f828cc6
commit 69ae1c08ef
5 changed files with 204 additions and 1 deletions

View File

@ -77,6 +77,68 @@ class IDF_Views_Issue
$params, $request);
}
/**
* View the issue summary.
* TODO Add thoses data in cache, and process it only after an issue update
*/
public $summary_precond = array('IDF_Precondition::accessIssues');
public function summary($request, $match)
{
$prj = $request->project;
$opened = $prj->getIssueCountByStatus('open');
$closed = $prj->getIssueCountByStatus('closed');
$otags = implode(',', $prj->getTagIdsByStatus('open'));
// Issue status statistics
$status = array();
$status['Open'] = array($opened, (int)(100 * $opened / ($opened + $closed)));
$status['Closed'] = array($closed, (int)(100 * $closed / ($opened + $closed)));
// Issue owner statistics
$sqlIssueTable = Pluf::factory('IDF_Issue')->getSqlTable();
$sqlUsersTable = Pluf::factory('Pluf_User')->getSqlTable();
$query = <<<"QUERY"
SELECT CONCAT(first_name, " ", last_name) as name, nb FROM (SELECT uid as id,count(uid) as nb FROM (SELECT ifnull(owner, -1) as uid FROM $sqlIssueTable WHERE status IN ($otags)) as ff group by uid) AS ff LEFT JOIN $sqlUsersTable using(id)
QUERY;
$db = Pluf::db();
$dbData = $db->select($query);
$ownerStatistics = array();
foreach ($dbData as $k => $v) {
$key = ($v['name'] === null) ? __('Not assigned') : $v['name'];
$ownerStatistics[$key] = array($v['nb'], (int)(100 * $v['nb'] / $opened));
}
// Issue class tag statistics
$tags = $prj->getTagCloud();
$tagStatistics = array();
foreach ($tags as $t) {
$tagStatistics[$t->class][$t->name] = array($t->nb_use, $t->id);
}
foreach($tagStatistics as $k => $v) {
$nbIssueInClass = 0;
foreach ($v as $val) {
$nbIssueInClass += $val[0];
}
foreach ($v as $kk => $vv) {
$tagStatistics[$k][$kk] = array($vv[0], (int)(100 * $vv[0] / $nbIssueInClass), $vv[1]);
}
}
// Sort
krsort($tagStatistics);
arsort($ownerStatistics);
$title = sprintf(__('Summary of tracked issues in %s.'), (string) $prj);
return Pluf_Shortcuts_RenderToResponse('idf/issues/summary.html',
array('page_title' => $title,
'project' => $prj,
'tagStatistics' => $tagStatistics,
'ownerStatistics' => $ownerStatistics,
'status' => $status,
),
$request);
}
/**
* View the issues watch list of a given user.
* Limited to a specified project

View File

@ -117,6 +117,11 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/$#',
'base' => $base,
'model' => 'IDF_Views_Issue',
'method' => 'index');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/summary/$#',
'base' => $base,
'model' => 'IDF_Views_Issue',
'method' => 'summary');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/$#',
'base' => $base,

View File

@ -2,7 +2,8 @@
{block tabissues} class="active"{/block}
{block subtabs}
<div id="sub-tabs">
<a {if $inOpenIssues}class="active" {/if}href="{url 'IDF_Views_Issue::index', array($project.shortname)}">{trans 'Open Issues'}</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>
{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>
| <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">

View File

@ -0,0 +1,89 @@
{extends "idf/issues/base.html"}
{block docclass}yui-t2{assign $inSummaryIssues=true}{/block}
{block body}
<div class='issue-summary'>
{foreach $tagStatistics as $key => $class}
<div>
<h2>Unresolved: By {$key}</h2>
<table class='issue-summary'>
<tbody>
{foreach $class as $key => $value}
<tr>
<td class="name"><a href="{url 'IDF_Views_Issue::listLabel', array($project.shortname, $value[2], 'open')}">{$key}</a></td>
<td class="count">{$value[0]}</td>
<td class="graph">
<table class='graph'>
<tbody><tr>
<td style="width:{$value[1] * 0.8}%" class="graph-color" valign="center">
<div class="colour-bar"></div>
</td>
<td>&nbsp;&nbsp;&nbsp;{$value[1]}%</td>
</tr>
</tbody>
</table>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{/foreach}
</div>
<div class='issue-summary'>
<div>
<h2>Status Summary</h2>
<table class='issue-summary'>
<tbody>
{foreach $status as $key => $value}
<tr>
<td class="name"><a href="{url 'IDF_Views_Issue::listStatus', array($project.shortname, $key)}">{$key}</a></td>
<td class="count">{$value[0]}</td>
<td class="graph">
<table class='graph'>
<tbody><tr>
<td style="width:{$value[1] * 0.8}%" class="graph-color" valign="center">
<div class="colour-bar"></div>
</td>
<td>&nbsp;&nbsp;&nbsp;{$value[1]}%</td>
</tr>
</tbody>
</table>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<div>
<h2>Unresolved: By Assignee</h2>
<table class='issue-summary'>
<tbody>
{foreach $ownerStatistics as $key => $value}
<tr>
<td class="name">{$key}</td>
<td class="count">{$value[0]}</td>
<td class="graph">
<table class='graph'>
<tbody><tr>
<td style="width:{$value[1] * 0.8}%" class="graph-color" valign="center">
<div class="colour-bar"></div>
</td>
<td>&nbsp;&nbsp;&nbsp;{$value[1]}%</td>
</tr>
</tbody>
</table>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
{/block}

View File

@ -1104,3 +1104,49 @@ div.p-list-private {
right: -3px;
position: relative;
}
/*
* Issue summary
*/
div.issue-summary {
float: left;
width: 50%;
}
div.issue-summary > div {
margin-right: 3em;
padding-top: 1em;
}
div.issue-summary h2 {
border-bottom: 1px solid #A5E26A;
}
table.issue-summary {
width: 100%;
}
table.issue-summary tr td {
border: 0;
padding: .1em;
}
table.issue-summary td.graph {
width: 60%;
}
table.issue-summary td.count {
text-align: right;
padding-right: .5em;
}
table.graph {
width: 100%;
margin: 0;
padding: 0;
}
td.graph-color {
background: #3C78B5;
}