This commit is contained in:
liugang
2017-11-02 16:30:16 +08:00
25 changed files with 104 additions and 288 deletions
+3
View File
@@ -110,6 +110,7 @@ $lang->action->desc->svncommited = '$date, submitted by <strong>$actor</stron
$lang->action->desc->gitcommited = '$date, submitted by <strong>$actor</strong> and the version is <strong>#$extra</strong>.' . "\n";
$lang->action->desc->finished = '$date, finished by <strong>$actor</strong>.' . "\n";
$lang->action->desc->paused = '$date, paused by <strong>$actor</strong>.' . "\n";
$lang->action->desc->verified = '$date, verified by <strong>$actor</strong>.' . "\n";
$lang->action->desc->diff1 = '<strong><i>%s</i></strong> has been changed. Its value was "%s" and the new value is "%s".<br />' . "\n";
$lang->action->desc->diff2 = '<strong><i>%s</i></strong> has been changed. The difference is ' . "\n" . "<blockquote>%s</blockquote>" . "\n<div class='hidden'>%s</div>";
$lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n";
@@ -171,6 +172,7 @@ $lang->action->label->editestimate = 'Edited Man-Hour';
$lang->action->label->canceled = 'Cancelled';
$lang->action->label->finished = 'Finished';
$lang->action->label->paused = 'Paused';
$lang->action->label->paused = 'Verified';
$lang->action->label->delayed = 'Delayed';
$lang->action->label->suspended = 'Suspended';
$lang->action->label->login = 'Login';
@@ -262,5 +264,6 @@ $lang->action->search->label['editestimate'] = $lang->action->label->edit
$lang->action->search->label['canceled'] = $lang->action->label->canceled;
$lang->action->search->label['finished'] = $lang->action->label->finished;
$lang->action->search->label['paused'] = $lang->action->label->paused;
$lang->action->search->label['verified'] = $lang->action->label->verified;
$lang->action->search->label['login'] = $lang->action->label->login;
$lang->action->search->label['logout'] = $lang->action->label->logout;
+3
View File
@@ -112,6 +112,7 @@ $lang->action->desc->svncommited = '$date, 由 <strong>$actor</strong> 提交
$lang->action->desc->gitcommited = '$date, 由 <strong>$actor</strong> 提交代码,版本为<strong>#$extra</strong>。' . "\n";
$lang->action->desc->finished = '$date, 由 <strong>$actor</strong> 完成。' . "\n";
$lang->action->desc->paused = '$date, 由 <strong>$actor</strong> 暂停。' . "\n";
$lang->action->desc->verified = '$date, 由 <strong>$actor</strong> 验收。' . "\n";
$lang->action->desc->diff1 = '修改了 <strong><i>%s</i></strong>,旧值为 "%s",新值为 "%s"。<br />' . "\n";
$lang->action->desc->diff2 = '修改了 <strong><i>%s</i></strong>,区别为:' . "\n" . "<blockquote>%s</blockquote>" . "\n<div class='hidden'>%s</div>";
$lang->action->desc->diff3 = '将文件名 %s 改为 %s 。' . "\n";
@@ -173,6 +174,7 @@ $lang->action->label->editestimate = '编辑了工时';
$lang->action->label->canceled = '取消了';
$lang->action->label->finished = '完成了';
$lang->action->label->paused = '暂停了';
$lang->action->label->verified = '验收了';
$lang->action->label->delayed = '延期';
$lang->action->label->suspended = '挂起';
$lang->action->label->login = '登录系统';
@@ -266,5 +268,6 @@ $lang->action->search->label['editestimate'] = $lang->action->label->edit
$lang->action->search->label['canceled'] = $lang->action->label->canceled;
$lang->action->search->label['finished'] = $lang->action->label->finished;
$lang->action->search->label['paused'] = $lang->action->label->paused;
$lang->action->search->label['verified'] = $lang->action->label->verified;
$lang->action->search->label['login'] = $lang->action->label->login;
$lang->action->search->label['logout'] = $lang->action->label->logout;
+1 -1
View File
@@ -23,7 +23,7 @@
<th width='60'><?php echo $lang->project->totalEstimate;?></th>
<th width='60'><?php echo $lang->project->totalConsumed;?></th>
<th width='60'><?php echo $lang->project->totalLeft;?></th>
<th width='115'><?php echo $lang->project->progess;?></th>
<th width='115'><?php echo $lang->project->progress;?></th>
<th width='100' class='{sorter: false}'><?php echo $lang->project->burn;?></th>
</tr>
</thead>
+1 -1
View File
@@ -6,7 +6,7 @@ $config->project->maxBurnDay = '31';
$config->project->weekend = '2';
$config->project->list = new stdclass();
$config->project->list->exportFields = 'id,name,code,PM,end,status,totalEstimate,totalConsumed,totalLeft,progess';
$config->project->list->exportFields = 'id,name,code,PM,end,status,totalEstimate,totalConsumed,totalLeft,progress';
global $lang, $app;
$app->loadLang('task');
+6 -12
View File
@@ -530,7 +530,7 @@ class project extends control
* @access public
* @return void
*/
public function story($projectID = 0, $orderBy = 'order', $type = 'byModule', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
public function story($projectID = 0, $orderBy = 'order_desc', $type = 'byModule', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
{
/* Load these models. */
$this->loadModel('story');
@@ -1254,7 +1254,7 @@ class project extends control
* @access public
* @return void
*/
public function kanban($projectID, $type = 'story', $orderBy = 'pri_asc')
public function kanban($projectID, $type = 'story', $orderBy = 'order_asc')
{
/* Save to session. */
$uri = $this->app->getURI(true);
@@ -2010,17 +2010,11 @@ class project extends control
$idList = explode(',', trim($this->post->storys, ','));
$orderBy = $this->post->orderBy;
$stories = $this->dao->select('story,`order`')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
->where('t1.story')->in($idList)
->andWhere('t1.project')->eq($projectID)
->orderBy($orderBy)
->fetchPairs('order', 'story');
foreach($stories as $order => $id)
$order = $this->dao->select('*')->from(TABLE_PROJECTSTORY)->where('story')->in($idList)->andWhere('project')->eq($projectID)->orderBy('order_asc')->fetch('order');
foreach($idList as $storyID)
{
$newID = array_shift($idList);
if($id == $newID) continue;
$this->dao->update(TABLE_PROJECTSTORY)->set('`order`')->eq($order)->where('story')->eq($newID)->andWhere('project')->eq($projectID)->exec();
$this->dao->update(TABLE_PROJECTSTORY)->set('`order`')->eq($order)->where('story')->eq($storyID)->andWhere('project')->eq($projectID)->exec();
$order++;
}
}
+3
View File
@@ -86,6 +86,9 @@ table th.col-closed {width:14%}
.board-story.stage-tested.inverse {background-color:#827717;}
.board-story.stage-released.inverse {background-color:#9C27B0;}
.board-assignedTo {color:#D2322D; background-color: #FFEBEE;}
.board-finishedBy {color:#229F24; background-color: #E8F5E9;}
.bug-pri,.task-pri {display: inline-block; width: 16px; height: 16px; text-align: center; border-radius: 8px; border: 1px solid #ddd; font-size: 12px; line-height: 14px;}
.affix {position:fixed; top:0px; width:95%;z-index:1030;}
+6 -7
View File
@@ -12,7 +12,6 @@
#kanbanWrapper tbody td {vertical-align: top; padding: 6px}
#kanbanWrapper tbody th {background: #f1f1f1}
#kanbanWrapper .board-shadow {height: 0; opacity: 0; transition: opacity 0.2s;}
#kanbanWrapper tbody tr.dragging td.col-droppable {background: #fff4e5}
#kanbanWrapper tbody tr.dragging td.col-droppable.drop-to {background: #ffeacc}
#kanbanWrapper tbody tr.dragging td.col-droppable.drop-to .board-story + .board-shadow {margin-top: 6px;}
#kanbanWrapper tbody tr.dragging td.col-droppable.drop-to .board-shadow {height: 28px; background: #999; background: rgba(0,0,0,0.35); opacity: 1;}
@@ -56,12 +55,12 @@
.story-pri.pri-4 {background-color:#795523;}
.board-story {color: #dd7503; background-color: #FFF3E0;}
.board-story.stage-projected {color:#777;}
.board-story.stage-developing {color:#D2322D; background-color: #FFEBEE;}
.board-story.stage-developed {color:#229F24; background-color: #E8F5E9;}
.board-story.stage-testing {color:#EF6C00; background-color: #FFF3E0;}
.board-story.stage-tested {color:#827717; background-color: #F9FBE7}
.board-story.stage-released {color:#9C27B0; background-color: #F3E5F5}
.board-story.board-story-projected {color:#777;}
.board-story.board-story-developing {color:#D2322D; background-color: #FFEBEE;}
.board-story.board-story-developed {color:#229F24; background-color: #E8F5E9;}
.board-story.board-story-testing {color:#EF6C00; background-color: #FFF3E0;}
.board-story.board-story-tested {color:#827717; background-color: #F9FBE7}
.board-story.board-story-released {color:#9C27B0; background-color: #F3E5F5}
.affix {position:fixed; top:0px; width:95%;z-index:1030;}
#kanbanHeader.affix {box-shadow: 0 3px 10px rgba(0,0,0,.1);}
+8 -1
View File
@@ -6,7 +6,14 @@ $(function()
{
var list = '';
for(i = 0; i < data.list.length; i++) list += $(data.list[i]).attr('data-id') + ',';
$.post(createLink('project', 'storySort', 'projectID=' + projectID), {'storys' : list, 'orderBy' : orderBy});
$.post(createLink('project', 'storySort', 'projectID=' + projectID), {'storys' : list, 'orderBy' : orderBy}, function()
{
var $target = $(data.element[0]);
$target.hide();
$target.fadeIn(1000);
order = 'order_asc'
history.pushState({}, 0, createLink('project', 'story', "projectID=" + projectID + '&orderBy=' + order));
});
});
fixedTfootAction('#projectStoryForm');
+3 -3
View File
@@ -38,7 +38,7 @@ $lang->project->totalEstimate = 'Est.';
$lang->project->totalConsumed = 'Consumed';
$lang->project->totalLeft = 'Total Remained';
$lang->project->Left = 'Remained';
$lang->project->progess = 'Progess';
$lang->project->progress = 'Progress';
$lang->project->hours = 'Estimate %s, Consumed %s, Remained %s';
$lang->project->viewBug = 'Bugs';
$lang->project->noProduct = "No {$lang->productCommon}";
@@ -238,10 +238,10 @@ $lang->project->placeholder->totalLeft = 'Total man-hour remained when start Pro
$lang->project->selectGroup = new stdclass();
$lang->project->selectGroup->done = '(Done)';
$lang->project->orderList['order_asc'] = "Order Asc";
$lang->project->orderList['order_desc'] = "Order Desc";
$lang->project->orderList['pri_asc'] = "Priority Asc";
$lang->project->orderList['pri_desc'] = "Priority Desc";
$lang->project->orderList['id_asc'] = "ID Asc";
$lang->project->orderList['id_desc'] = "ID Desc";
$lang->project->orderList['stage_asc'] = "Stage Asc";
$lang->project->orderList['stage_desc'] = "Stage Desc";
+3 -3
View File
@@ -38,7 +38,7 @@ $lang->project->totalEstimate = '总预计';
$lang->project->totalConsumed = '总消耗';
$lang->project->totalLeft = '总剩余';
$lang->project->Left = '剩余';
$lang->project->progess = '进度';
$lang->project->progress = '进度';
$lang->project->hours = '预计 %s 消耗 %s 剩余 %s';
$lang->project->viewBug = '查看bug';
$lang->project->noProduct = "无{$lang->productCommon}{$lang->projectCommon}";
@@ -238,10 +238,10 @@ $lang->project->placeholder->totalLeft = '项目开始时的总预计工时';
$lang->project->selectGroup = new stdclass();
$lang->project->selectGroup->done = '(已结束)';
$lang->project->orderList['order_asc'] = "需求排序正序";
$lang->project->orderList['order_desc'] = "需求排序倒序";
$lang->project->orderList['pri_asc'] = "需求优先级正序";
$lang->project->orderList['pri_desc'] = "需求优先级倒序";
$lang->project->orderList['id_asc'] = "需求ID正序";
$lang->project->orderList['id_desc'] = "需求ID倒序";
$lang->project->orderList['stage_asc'] = "需求阶段正序";
$lang->project->orderList['stage_desc'] = "需求阶段倒序";
+1 -1
View File
@@ -38,7 +38,7 @@ $lang->project->totalEstimate = '總預計';
$lang->project->totalConsumed = '總消耗';
$lang->project->totalLeft = '總剩餘';
$lang->project->Left = '剩餘';
$lang->project->progess = '進度';
$lang->project->progress = '進度';
$lang->project->hours = '預計 %s 消耗 %s 剩餘 %s';
$lang->project->viewBug = '查看bug';
$lang->project->noProduct = "無{$lang->productCommon}{$lang->projectCommon}";
+1
View File
@@ -2314,6 +2314,7 @@ class projectModel extends model
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->where('t1.project')->eq((int)$projectID)
->andWhere('t2.deleted')->eq(0)
->orderBy('t1.`order`_desc')
->fetchAll();
$storyGroups = array();
foreach($stories as $story) $storyGroups[$story->product][$story->module][$story->id] = $story;
+1 -1
View File
@@ -42,7 +42,7 @@
<th class='w-70px'><?php echo $lang->project->totalEstimate;?></th>
<th class='w-70px'><?php echo $lang->project->totalConsumed;?></th>
<th class='w-70px'><?php echo $lang->project->totalLeft;?></th>
<th class='w-150px'><?php echo $lang->project->progess;?></th>
<th class='w-150px'><?php echo $lang->project->progress;?></th>
<th class='w-100px'><?php echo $lang->project->burn;?></th>
<?php if($canOrder):?>
<th class='w-60px sort-default'><?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
+1 -1
View File
@@ -117,7 +117,7 @@
<div class='input-group'>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)'");?>
<span class='input-group-addon fix-border' style='padding:0px'></span>
<?php if($product->type != 'normal') echo html::select("branch[$i]", $branchGroups[$product->id], $product->branch, "class='form-control' style='width:80px'")?>
<?php if($product->type != 'normal' and isset($branchGroups[$product->id])) echo html::select("branch[$i]", $branchGroups[$product->id], $product->branch, "class='form-control' style='width:80px'")?>
</div>
</div>
<?php $i++;?>
+13 -8
View File
@@ -27,18 +27,23 @@ $account = $this->app->user->account
<?php $hasGroupCol = (($type == 'story' and count($stories) > 0) or $type != 'story');?>
<?php if($hasGroupCol):?>
<th class='w-p15 col-story'>
<?php if($type == 'story'):?>
<div class='dropdown inline-block'>
<a data-toggle='dropdown' href='javascript:;'><?php echo $lang->project->orderList[$orderBy]?> <span class='icon-caret-down'></span> </a>
<a data-toggle='dropdown' href='javascript:;'>
<?php if($type == 'story'):?>
<?php echo $lang->project->orderList[$orderBy]?>
<?php else:?>
<?php echo $lang->task->$type;?>
<?php endif;?>
<span class='icon-caret-down'></span>
</a>
<ul class='dropdown-menu text-left'>
<?php foreach ($lang->project->orderList as $key => $value):?>
<li <?php echo $orderBy == $key ? " class='active'" : '' ?>><?php echo html::a($this->createLink('project', 'kanban', "projectID=$projectID&type=story&orderBy=$key"), $value);?></li>
<?php endforeach;?>
<?php foreach ($lang->project->orderList as $key => $value):?>
<li <?php echo ($type == 'story' and $orderBy == $key) ? " class='active'" : '' ?>><?php echo html::a($this->createLink('project', 'kanban', "projectID=$projectID&type=story&orderBy=$key"), $value);?></li>
<?php endforeach;?>
<?php echo "<li" . ($type == 'assignedTo' ? " class='active'" : '') . ">" . html::a(inlink('kanban', "project=$projectID&type=assignedTo"), $lang->project->groups['assignedTo']) . "</li>";?>
<?php echo "<li" . ($type == 'finishedBy' ? " class='active'" : '') . ">" . html::a(inlink('kanban', "project=$projectID&type=finishedBy"), $lang->project->groups['finishedBy']) . "</li>";?>
</ul>
</div>
<?php else:?>
<?php echo $lang->task->$type;?>
<?php endif;?>
</th>
<?php endif;?>
<?php $endCol = array_pop($taskCols);?>
+11 -9
View File
@@ -16,12 +16,14 @@
<?php js::set('moduleID', ($type == 'byModule' ? $param : 0));?>
<?php js::set('productID', ($type == 'byProduct' ? $param : 0));?>
<?php js::set('confirmUnlinkStory', $lang->project->confirmUnlinkStory)?>
<div id='titlebar'>
<div class='heading'><?php echo html::icon($lang->icons['story']);?> <?php echo $lang->project->story;?></div>
<div id='featurebar'>
<ul class='nav'>
<li class='active'><?php if(common::hasPriv('project', 'story')) echo html::a($this->createLink('project', 'story', "project=$project->id"), $lang->project->story);?></li>
<li><?php if(common::hasPriv('project', 'storykanban')) echo html::a($this->createLink('project', 'storykanban', "project=$project->id"), $lang->project->kanban);?></li>
</ul>
<div class='actions'>
<div class='btn-group'>
<?php
common::printIcon('project', 'storyKanban', "project=$project->id", '', 'button', 'columns', '', '', '', '', $lang->project->kanban);
common::printIcon('story', 'export', "productID=$productID&orderBy=id_desc", '', 'button', '', '', 'export');
$this->lang->story->create = $this->lang->project->createStory;
@@ -62,6 +64,9 @@
<tr class='colhead'>
<?php $vars = "projectID={$project->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<?php if($canOrder):?>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
<?php endif;?>
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='{sorter:false}'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
@@ -73,9 +78,6 @@
<th title='<?php echo $lang->story->bugCount?>' class='w-30px'><?php echo $lang->story->bugCountAB;?></th>
<th title='<?php echo $lang->story->caseCount?>' class='w-30px'><?php echo $lang->story->caseCountAB;?></th>
<th class='w-110px {sorter:false}'> <?php echo $lang->actions;?></th>
<?php if($canOrder):?>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
<?php endif;?>
</tr>
</thead>
<tbody id='storyTableList' class='sortable'>
@@ -96,6 +98,9 @@
<?php endif;?>
<?php echo html::a($storyLink, sprintf('%03d', $story->id));?>
</td>
<?php if($canOrder):?>
<td class='sort-handler'><i class='icon-move'></i></td>
<?php endif;?>
<td><span class='<?php echo 'pri' . zget($lang->story->priList, $story->pri, $story->pri)?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td class='text-left' title="<?php echo $story->title?>">
<?php if(isset($branchGroups[$story->product][$story->branch])) echo "<span class='label label-info label-badge'>" . $branchGroups[$story->product][$story->branch] . '</span>';?>
@@ -152,9 +157,6 @@
}
?>
</td>
<?php if($canOrder):?>
<td class='sort-handler'><i class='icon-move'></i></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
+9 -10
View File
@@ -10,12 +10,14 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('confirmUnlinkStory', $lang->project->confirmUnlinkStory)?>
<div id='titlebar'>
<div class='heading'><?php echo html::icon($lang->icons['story']);?> <?php echo $lang->project->story;?></div>
<div id='featurebar'>
<ul class='nav'>
<li><?php if(common::hasPriv('project', 'story')) echo html::a($this->createLink('project', 'story', "project=$project->id"), $lang->project->story);?></li>
<li class='active'><?php if(common::hasPriv('project', 'storykanban')) echo html::a($this->createLink('project', 'storykanban', "project=$project->id"), $lang->project->kanban);?></li>
</ul>
<div class='actions'>
<div class='btn-group'>
<?php
common::printIcon('project', 'story', "project=$project->id", '', 'button', 'list', '', '', '', '', $lang->project->story);
common::printIcon('story', 'export', "productID=$productID&orderBy=id_desc", '', 'button', '', '', 'export');
$this->lang->story->create = $this->lang->project->createStory;
@@ -43,15 +45,12 @@ $account = $this->app->user->account
<table class='boards-layout table' id='kanbanHeader'>
<thead>
<tr>
<?php $endCol = array_pop($cols);?>
<?php foreach ($cols as $col):?>
<th class='col-<?php echo $col?>'><?php echo $lang->story->stageList[$col];?></th>
<?php endforeach;?>
<th class='col-<?php echo $endCol?>'><?php echo $lang->story->stageList[$endCol];?></th>
</tr>
</thead>
</table>
<?php $cols[] = $endCol;?>
<table class='boards-layout table active-disabled table-bordered' id='kanbanWrapper'>
<thead>
<tr>
@@ -64,7 +63,7 @@ $account = $this->app->user->account
<td class='col-droppable col-<?php echo $col?>' data-id='<?php echo $col?>'>
<?php if(!empty($stories[$col])):?>
<?php foreach($stories[$col] as $story):?>
<div class='board board-story board-story-<?php echo $col ?>;?>' data-id='<?php echo $story->id?>' id='task-<?php echo $story->id?>'>
<div class='board board-story board-story-<?php echo $col; ?>' data-id='<?php echo $story->id?>' id='story-<?php echo $story->id?>'>
<div class='board-title'>
<?php echo html::a($this->createLink('story', 'view', "story=$story->id", '', true), $story->title, '', 'class="kanbanFrame" title="' . $story->title . '"');?>
<div class='board-actions'>
@@ -80,10 +79,10 @@ $account = $this->app->user->account
</div>
</div>
<div class='board-footer clearfix'>
<span class='task-id board-id' title='<?php echo $lang->story->id?>'><?php echo $story->id?></span>
<span class='task-pri pri-<?php echo $story->pri?>' title='<?php echo $lang->story->pri?>'></span>
<span class='story-id board-id' title='<?php echo $lang->story->id?>'><?php echo $story->id?></span>
<span class='story-pri pri-<?php echo $story->pri?>' title='<?php echo $lang->story->pri?>'></span>
<div class='pull-right'>
<span class='task-left' title='<?php echo $lang->story->status?>'><?php echo zget($this->lang->story->statusList, $story->status, '');?></span>
<span class='text-left' title='<?php echo $lang->story->status?>'><?php echo zget($this->lang->story->statusList, $story->status, '');?></span>
</div>
</div>
</div>
-211
View File
@@ -1,211 +0,0 @@
<?php
/**
* The task data view file of project module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package project
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/tablesorter.html.php';?>
<?php $columns = 12; ?>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed table-selectable' id='taskList'>
<thead>
<tr>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='{sorter:false}'> <?php common::printOrderLink('name', $orderBy, $vars, $lang->task->name);?></th>
<th class='w-100px {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='w-70px {sorter:false}'> <?php common::printOrderLink('deadline', $orderBy, $vars, $lang->task->deadlineAB);?></th>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<?php $columns++; ?>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('openedDate', $orderBy, $vars, $lang->task->openedDateAB);?></th>
<?php endif;?>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->task->assignedToAB);?></th>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedByAB);?></th>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<?php $columns++; ?>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('finishedDate', $orderBy, $vars, $lang->task->finishedDateAB);?></th>
<?php endif;?>
<th class='w-35px {sorter:false}'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
<th class='w-40px nobr {sorter:false}'> <?php common::printOrderLink('left', $orderBy, $vars, $lang->task->leftAB);?></th>
<th class='w-50px' title='<?php echo $lang->task->progessTips?>'><?php echo $lang->task->progess;?></th>
<?php if($project->type == 'sprint'): ?>
<th class='w-100px {sorter:false}'><?php common::printOrderLink('story', $orderBy, $vars, $lang->task->story); ?></th>
<?php $columns++; ?>
<?php endif;?>
<th class='w-170px {sorter:false}'><?php echo $lang->actions;?></th>
</tr>
</thead>
<?php if($tasks):?>
<tbody>
<?php foreach($tasks as $task):?>
<?php $class = $task->assignedTo == $app->user->account ? 'style=color:red' : ''; ?>
<tr class='text-center'>
<td class='cell-id'>
<input type='checkbox' name='taskIDList[<?php echo $task->id;?>]' value='<?php echo $task->id;?>'/>
<?php if(!common::printLink('task', 'view', "task=$task->id", sprintf('%03d', $task->id))) printf('%03d', $task->id);?>
</td>
<td><span class='<?php echo 'pri' . zget($lang->task->priList, $task->pri, $task->pri)?>'><?php echo $task->pri == '0' ? '' : zget($lang->task->priList, $task->pri, $task->pri);?></span></td>
<td class='text-left' title="<?php echo $task->name?>">
<?php if(isset($branchGroups[$task->product][$task->branch])) echo "<span title='{$lang->product->branchName[$task->productType]}' class='label label-branch label-badge'>" . $branchGroups[$task->product][$task->branch] . '</span>';?>
<?php if($modulePairs and $task->module) echo "<span title='{$lang->task->module}' class='label label-info label-badge'>" . $modulePairs[$task->module] . '</span>';?>
<?php
if(!common::printLink('task', 'view', "task=$task->id", $task->name, null, "style='color: $task->color'")) echo $task->name;
if($task->fromBug) echo html::a($this->createLink('bug', 'view', "id=$task->fromBug"), "[BUG#$task->fromBug]", '_blank', "class='bug'");
?>
</td>
<td class="<?php echo $task->status;?>">
<?php
$storyChanged = ($task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion);
if($storyChanged)
{
echo "(<span class='warning'>{$lang->story->changed}</span> ";
echo html::a($this->createLink('task', 'confirmStoryChange', "taskID=$task->id"), $lang->confirm, 'hiddenwin');
echo ")";
}
else
{
echo $lang->task->statusList[$task->status];
}
?>
</td>
<td class="<?php if(isset($task->delay)) echo 'delayed';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo substr($task->deadline, 5, 6);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($task->openedDate, 5, 6);?></td>
<?php endif;?>
<td <?php echo $class;?>><?php echo $task->assignedTo == 'closed' ? 'Closed' : zget($users, $task->assignedTo, $task->assignedTo);?></td>
<td><?php echo zget($users, $task->finishedBy, $task->finishedBy);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($task->finishedDate, 5, 6);?></td>
<?php endif;?>
<td><?php echo $task->estimate;?></td>
<td><?php echo $task->consumed;?></td>
<td><?php echo $task->left;?></td>
<td><?php echo $task->progess?>%</td>
<?php
if($project->type == 'sprint')
{
echo '<td class="text-left" title="' . $task->storyTitle . '">';
if($task->storyID)
{
if(!common::printLink('story', 'view', "storyid=$task->storyID", $task->storyTitle)) print $task->storyTitle;
}
echo '</td>';
}
?>
<td class='text-right'>
<?php
common::printIcon('task', 'assignTo', "projectID=$task->project&taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
if($browseType == 'needconfirm')
{
$lang->task->confirmStoryChange = $lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin');
}
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list');
common::printIcon('task', 'batchCreate', "project=$projectID&storyID=&moduleID=$moduleID&taskID=$task->id", $task, 'list','plus','','','','',$lang->task->children);
?>
</td>
</tr>
<?php if($task->children):?>
<?php foreach($task->children as $child):?>
<?php $class = $child->assignedTo == $app->user->account ? 'style=color:red' : ''; ?>
<tr class='text-center table-children parent-<?php echo $task->id;?>'>
<td class='cell-id'>
<input type='checkbox' name='taskIDList[<?php echo $child->id;?>]' value='<?php echo $child->id;?>'/>
<?php if(!common::printLink('task', 'view', "task=$child->id", sprintf('%03d', $child->id))) printf('%03d', $child->id);?>
</td>
<td><span class='<?php echo 'pri' . zget($lang->task->priList, $child->pri, $child->pri)?>'><?php echo $child->pri == '0' ? '' : zget($lang->task->priList, $child->pri, $child->pri);?></span></td>
<td class='text-left' title="<?php echo $child->name?>">
<?php if(isset($branchGroups[$child->product][$child->branch])) echo "<span title='{$lang->product->branchName[$child->productType]}' class='label label-branch label-badge'>" . $branchGroups[$child->product][$child->branch] . '</span>';?>
<?php if($modulePairs and $child->module) echo "<span title='{$lang->task->module}' class='label label-info label-badge'>" . $modulePairs[$child->module] . '</span>';?>
<?php
if(!common::printLink('task', 'view', "task=$child->id", $child->name, null, "style='color: $child->color'")) echo $child->name;
if($child->fromBug) echo html::a($this->createLink('bug', 'view', "id=$child->fromBug"), "[BUG#$child->fromBug]", '_blank', "class='bug'");
?>
</td>
<td class="<?php echo $child->status;?>">
<?php
$storyChanged = ($child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion);
if($storyChanged)
{
echo "(<span class='warning'>{$lang->story->changed}</span> ";
echo html::a($this->createLink('task', 'confirmStoryChange', "taskID=$child->id"), $lang->confirm, 'hiddenwin');
echo ")";
}
else
{
echo $lang->task->statusList[$child->status];
}
?>
</td>
<td class="<?php if(isset($child->delay)) echo 'delayed';?>"><?php if(substr($child->deadline, 0, 4) > 0) echo substr($child->deadline, 5, 6);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($child->openedDate, 5, 6);?></td>
<?php endif;?>
<td <?php echo $class;?>><?php echo $child->assignedTo == 'closed' ? 'Closed' : zget($users, $child->assignedTo, $child->assignedTo);?></td>
<td><?php echo zget($users, $child->finishedBy, $child->finishedBy);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($child->finishedDate, 5, 6);?></td>
<?php endif;?>
<td><?php echo $child->estimate;?></td>
<td><?php echo $child->consumed;?></td>
<td><?php echo $child->left;?></td>
<td><?php echo $child->progess?>%</td>
<?php
if($project->type == 'sprint')
{
echo '<td class="text-left" title="' . $child->storyTitle . '">';
if($child->storyID)
{
if(!common::printLink('story', 'view', "storyid=$child->storyID", $child->storyTitle)) print $child->storyTitle;
}
echo '</td>';
}
?>
<td class='text-right'>
<?php
common::printIcon('task', 'assignTo', "projectID=$child->project&taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
if($browseType == 'needconfirm')
{
$lang->task->confirmStoryChange = $lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$child->id", '', 'list', '', 'hiddenwin');
}
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list');
common::printIcon('task', 'batchCreate', "", $child, 'list','plus','','','','',$lang->task->children);
?>
</td>
</tr>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
</tbody>
<?php endif?>
+3 -1
View File
@@ -933,9 +933,11 @@ class story extends control
$storyIDList = array_unique($storyIDList);
$allChanges = $this->story->batchChangeStage($storyIDList, $stage);
if(dao::isError()) die(js::error(dao::getError()));
$action = $stage == 'verified' ? 'Verified' : 'Edited';
foreach($allChanges as $storyID => $changes)
{
$actionID = $this->action->create('story', $storyID, 'Edited');
$actionID = $this->action->create('story', $storyID, $action);
$this->action->logHistory($actionID, $changes);
$this->story->sendmail($storyID, $actionID);
}
+6 -2
View File
@@ -40,7 +40,7 @@ class storyModel extends model
$story->projects = $this->dao->select('t1.project, t2.name, t2.status')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t1.story')->eq($storyID)
->orderBy('t1.project DESC')
->orderBy('t1.`order` DESC')
->fetchAll('project');
$story->tasks = $this->dao->select('id, name, assignedTo, project, status, consumed, `left`')->from(TABLE_TASK)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->orderBy('id DESC')->fetchGroup('project');
$story->stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->eq($storyID)->fetchPairs('branch', 'stage');
@@ -976,6 +976,9 @@ class storyModel extends model
$story->lastEditedDate = $now;
$story->stage = $stage;
/* When stage is verified then only change to released. */
if($oldStory->stage == 'verified' and $stage->stage != 'released') $stage->stage = 'verified';
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq((int)$storyID)->exec();
if(!dao::isError()) $allChanges[$storyID] = common::createChanges($oldStory, $story);
}
@@ -1574,7 +1577,7 @@ class storyModel extends model
* @access public
* @return array
*/
public function getProjectStories($projectID = 0, $orderBy = 'pri_asc,id_desc', $type = 'byModule', $param = 0, $pager = null)
public function getProjectStories($projectID = 0, $orderBy = 't1.`order`_desc', $type = 'byModule', $param = 0, $pager = null)
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectStories();
@@ -1667,6 +1670,7 @@ class storyModel extends model
->beginIF($productID)->andWhere('t2.product')->eq((int)$productID)->fi()
->beginIF($branch)->andWhere('t2.branch')->in("0,$branch")->fi()
->beginIF($moduleIdList)->andWhere('t2.module')->in($moduleIdList)->fi()
->orderBy('t1.`order` desc')
->fetchAll();
if(!$stories) return array();
return $this->formatStories($stories, $type);
+1 -1
View File
@@ -58,7 +58,7 @@ if($config->global->flow == 'onlyTask')
}
$config->task->datatable = new stdclass();
$config->task->datatable->defaultField = array('id', 'pri', 'name', 'status', 'deadline', 'openedDate', 'assignedTo', 'finishedBy', 'estimate', 'consumed', 'left', 'story', 'actions');
$config->task->datatable->defaultField = array('id', 'pri', 'name', 'status', 'deadline', 'openedDate', 'assignedTo', 'finishedBy', 'estimate', 'consumed', 'left', 'actions');
$config->task->datatable->fieldList['id']['title'] = 'idAB';
$config->task->datatable->fieldList['id']['fixed'] = 'left';
+3 -3
View File
@@ -64,8 +64,8 @@ $lang->testreport->fromCaseBugTip= "Bug created after failure of use case in tes
$lang->testreport->errorTrunk = "The trunk version cannot create a test report. Please modify the associated version!";
$lang->testreport->bugSummary = <<<EOD
<strong>%s</strong> Bug(s) generated in total <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-warning-sign'></i></a>,
<strong>%s</strong> Bug(s) remained unresolve <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-warning-sign'></i></a>,
<strong>%s</strong> Bug(s) failure of case <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-warning-sign'></i></a>.
<strong>%s</strong> Bug(s) generated in total <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-info-sign'></i></a>,
<strong>%s</strong> Bug(s) remained unresolve <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-info-sign'></i></a>,
<strong>%s</strong> Bug(s) failure of case <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-info-sign></i></a>.
Confirmed bug rate(bug resolution is resolved or delayedg status is resolved or closed): <strong>%s</strong>,Bug created in caserate(Bugs created in cases / Newly generated bugs): <strong>%s</strong>'
EOD;
+3 -3
View File
@@ -64,8 +64,8 @@ $lang->testreport->fromCaseBugTip= "测试时间范围内,用例执行失败
$lang->testreport->errorTrunk = "主干版本不能创建测试报告,请修改关联版本!";
$lang->testreport->bugSummary = <<<EOD
共发现<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-warning-sign'></i></a>,
遗留<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-warning-sign'></i></a>。
用例执行产生<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-warning-sign'></i></a>。
共发现<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-info-sign'></i></a>,
遗留<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-info-sign'></i></a>。
用例执行产生<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-info-sign'></i></a>。
有效Bug率(方案为已解决或延期 / 状态为已解决或已关闭):<strong>%s</strong>,用例发现Bug率(用例创建的Bug / 发现Bug数):<strong>%s</strong>
EOD;
+10 -8
View File
@@ -110,6 +110,7 @@ class tutorialModel extends model
$story->duplicateStory = 0;
$story->version = 1;
$story->deleted = '0';
$story->order = '0';
$stories = array();
$stories[] = $story;
@@ -202,14 +203,15 @@ class tutorialModel extends model
public function getTeamMembers()
{
$member = new stdclass();
$member->project = 1;
$member->account = $this->app->user->account;
$member->role = $this->app->user->role;
$member->join = $this->app->user->join;
$member->days = 10;
$member->hours = 7.0;
$member->totalHours = 70.0;
$member->realname = $this->app->user->realname;
$member->project = 1;
$member->account = $this->app->user->account;
$member->role = $this->app->user->role;
$member->join = $this->app->user->join;
$member->days = 10;
$member->hours = 7.0;
$member->totalHours = 70.0;
$member->realname = $this->app->user->realname;
$member->limitedUser = 0;
return array($member->account => $member);
}
+4 -1
View File
@@ -1802,7 +1802,10 @@ class upgradeModel extends model
*/
public function initProjectStoryOrder()
{
$storyGroup = $this->dao->select('*')->from(TABLE_PROJECTSTORY)->orderBy('story_asc')->fetchGroup('project', 'story');
$storyGroup = $this->dao->select('t1.*')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
->orderBy('t2.pri_desc,t1.story_asc')
->fetchGroup('project', 'story');
foreach($storyGroup as $projectID => $stories)
{