Finish task#3253 优化看板卡片弹出菜单的位置,cost:1 left:0

Finish task#3243 看板增加自定义设置显示颜色的功能,cost:3 left:0
Finish task#3242 看板增加默认展开/折叠任务选项卡的功能,cost:1 left:0
Finish task#3241 看板增加显示/隐藏已关闭已取消任务的功能,cost:2 left:0
This commit is contained in:
wangyidong
2017-10-20 16:27:17 +08:00
parent 9043edd8ca
commit c312b64220
11 changed files with 261 additions and 37 deletions
+4
View File
@@ -321,6 +321,8 @@ $lang->resource->project->kanban = 'kanban';
$lang->resource->project->printKanban = 'printKanban';
$lang->resource->project->tree = 'tree';
$lang->resource->project->all = 'all';
$lang->resource->project->kanbanHideCols = 'kanbanHideCols';
$lang->resource->project->kanbanColsColor = 'kanbanColsColor';
$lang->project->methodOrder[0] = 'index';
$lang->project->methodOrder[5] = 'view';
@@ -360,6 +362,8 @@ $lang->project->methodOrder[175] = 'kanban';
$lang->project->methodOrder[180] = 'printKanban';
$lang->project->methodOrder[185] = 'tree';
$lang->project->methodOrder[190] = 'all';
$lang->project->methodOrder[195] = 'kanbanHideCols';
$lang->project->methodOrder[200] = 'kanbanColsColor';
/* Task. */
$lang->resource->task = new stdclass();
+8
View File
@@ -99,3 +99,11 @@ $config->printKanban->col['wait'] = 2;
$config->printKanban->col['doing'] = 3;
$config->printKanban->col['done'] = 4;
$config->printKanban->col['closed'] = 5;
$config->project->kanbanSetting = new stdclass();
$config->project->kanbanSetting->colorList['wait'] = '#2b529c';
$config->project->kanbanSetting->colorList['doing'] = '#d2323d';
$config->project->kanbanSetting->colorList['pause'] = '#e48600';
$config->project->kanbanSetting->colorList['done'] = '#229f24';
$config->project->kanbanSetting->colorList['cancel'] = '#333';
$config->project->kanbanSetting->colorList['closed'] = '#777';
+78
View File
@@ -1273,6 +1273,13 @@ class project extends control
$this->view->orderBy = $orderBy;
$this->view->projectID = $projectID;
$this->view->project = $project;
$kanbanSetting = $this->project->getKanbanSetting($projectID);
$this->view->allCols = $kanbanSetting->allCols;
$this->view->showOption = $kanbanSetting->showOption;
$this->view->colorList = $kanbanSetting->colorList;
$this->display();
}
@@ -1992,4 +1999,75 @@ class project extends control
{
$this->locate($this->createLink('doc', 'objectLibs', "type=project&objectID=$projectID&from=project"));
}
/**
* Kanban setting.
*
* @param int $projectID
* @access public
* @return void
*/
public function ajaxKanbanSetting($projectID)
{
if($_POST)
{
$this->loadModel('setting');
$data = fixer::input('post')->get();
if(common::hasPriv('project', 'kanbanHideCols'))
{
$allCols = array();
if(isset($this->config->project->kanbanSetting->allCols))
{
$allCols = json_decode($this->config->project->kanbanSetting->allCols, true);
}
$allCols[$projectID] = $data->allCols;
$this->setting->setItem("system.project.kanbanSetting.allCols", json_encode($allCols));
}
$account = $this->app->user->account;
$this->setting->setItem("{$account}.project.kanbanSetting.showOption", $data->showOption);
if(common::hasPriv('project', 'kanbanColsColor')) $this->setting->setItem("system.project.kanbanSetting.colorList", json_encode($data->colorList));
die(js::reload('parent.parent'));
}
$this->app->loadLang('task');
$kanbanSetting = $this->project->getKanbanSetting($projectID);
$this->view->allCols = $kanbanSetting->allCols;
$this->view->showOption = $kanbanSetting->showOption;
$this->view->colorList = $kanbanSetting->colorList;
$this->view->projectID = $projectID;
$this->display();
}
/**
* Ajax reset kanban setting
*
* @param int $projectID
* @param string $confirm
* @access public
* @return void
*/
public function ajaxResetKanban($projectID, $confirm = 'no')
{
if($confirm != 'yes')die(js::confirm($this->lang->kanbanSetting->noticeReset, inlink('ajaxResetKanban', "projectID=$projectID&confirm=yes")));
$this->loadModel('setting');
if(common::hasPriv('project', 'kanbanHideCols') and isset($this->config->project->kanbanSetting->allCols))
{
$allCols = json_decode($this->config->project->kanbanSetting->allCols, true);
unset($allCols[$projectID]);
$this->setting->setItem("system.project.kanbanSetting.allCols", json_encode($allCols));
}
$account = $this->app->user->account;
$this->setting->deleteItems("owner={$account}&module=project&section=kanbanSetting&key=showOption");
if(common::hasPriv('project', 'kanbanColsColor')) $this->setting->deleteItems("owner=system&module=project&section=kanbanSetting&key=colorList");
die(js::reload('parent.parent'));
}
}
+20 -20
View File
@@ -1,8 +1,8 @@
table th.col-closed {width:12%}
table th.col-closed {width:14%}
#kanbanHeader th{border: 1px solid #ddd; padding:8px;}
#kanbanHeader .dropdown {display: inline-block; margin-left: 10px;}
#kanbanHeader .dropdown {display: inline-block;}
#kanbanHeader .dropdown > a {color: #036}
#kanbanHeader th.col-closed {position: relative}
#kanbanHeader th{position: relative}
#kanbanHeader .actions {position: absolute; right: 0; top: 0; padding: 0px; background: #f1f1f1; border-left: 1px solid #ccc}
#kanbanHeader .actions .btn {display: block; border-radius: 0; width: 34px; height: 36px; position: relative; text-align: center; padding: 5px 0; color: #036}
#kanbanHeader .actions .btn-text {display: none}
@@ -39,7 +39,8 @@ table th.col-closed {width:12%}
.board .dropdown-menu > a {display: block; padding: 3px 15px; color: #333; font-size: 12px}
.board .dropdown-menu > a:hover {background: #f1f1f1; color: #1a53ff; text-decoration: none}
.board .dropdown-menu > a.disabled, .board .dropdown-menu > a.disabled:hover, .board .dropdown-menu > a.active {color: #aaa; background: none}
.board .board-footer {display: none; opacity: 0.9}
.board .board-footer {display: none; opacity: 0.6}
.board.inverse .board-footer {display: none; opacity: 0.9}
.board.show-info .board-footer {display: block; margin: 0 -6px -3px -6px; padding: 5px; background: rgba(0,0,0,0.07);}
.board-footer .board-id {display: inline-block; border: 1px solid #aaa; font-weight: normal; padding: 0px 4px; text-align: center; min-width: 20px; line-height: 16px; height: 17px; margin-right: 10px; font-size: 12px;}
.board-bug-closed .board-footer .bug-pri, .board-task-closed .board-footer .task-pri {border-color: #666}
@@ -60,13 +61,21 @@ table th.col-closed {width:12%}
.story-pri.pri-3 {background-color:#b56a00;}
.story-pri.pri-4 {background-color:#795523;}
.board {background: #ddd; color: #444; outline: 1px solid rgba(0,0,0,.1); outline-offset: -1px;}
.board-bug-wait,.board-task-wait {color: #2b529c; background-color: #E8EAF6}
.board-bug-doing,.board-task-doing {color: #D2322D; background-color: #FFEBEE;}
.board-task-pause {color: #fff; background-color: #E48600;}
.board-bug-done,.board-task-done {color: #229F24; background-color: #E8F5E9;}
.board-bug-closed,.board-task-closed {color: #666; background-color: #ccc;}
.board:hover {outline: 1px solid rgba(0,0,0,.3);}
.board {background: #333; color: #f1f1f1; outline: 1px solid rgba(0,0,0,.1); outline-offset: -1px;}
.board:hover {outline: 1px solid rgba(0,0,0,.3); color:#fff}
.board-bug-cancel, .board-task-cancel {background: #333; opacity: 0.7;}
.board-bug-wait, .board-task-wait {background: #2b529c;opacity: 0.7;}
.board-task-pause {background: #E48600;opacity: 0.7;}
.board-bug-doing, .board-task-doing {background: #D2322D;opacity: 0.7;}
.board-bug-done, .board-task-done {background: #229F24;opacity: 0.7;}
.board-bug-closed, .board-task-closed {background: #777; opacity: 0.7;}
.board-bug-cancel.inverse, .board-task-cancel.inverse {opacity: 1;}
.board-bug-wait.inverse, .board-task-wait.inverse {opacity: 1}
.board-task-pause.inverse {opacity: 1}
.board-bug-doing.inverse, .board-task-doing.inverse {opacity: 1}
.board-bug-done.inverse, .board-task-done.inverse {opacity: 1}
.board-bug-closed.inverse, .board-task-closed.inverse {opacity: 1}
.board-story {color: #dd7503; background-color: #FFF3E0;}
.board-story.stage-projected {color:#777;}
@@ -76,15 +85,6 @@ table th.col-closed {width:12%}
.board-story.stage-tested {color:#827717; background-color: #F9FBE7}
.board-story.stage-released {color:#9C27B0; background-color: #F3E5F5}
.board.inverse {background: #333; color: #f1f1f1;}
.board.inverse:hover {color: #fff;}
.board-bug-cancel.inverse, .board-task-cancel.inverse {background: #333;}
.board-bug-wait.inverse, .board-task-wait.inverse {background: #2b529c}
.board-task-pause.inverse {background: #E48600}
.board-bug-doing.inverse, .board-task-doing.inverse {background: #D2322D}
.board-bug-done.inverse, .board-task-done.inverse {background: #229F24}
.board-bug-closed.inverse, .board-task-closed.inverse {background: #777;}
.board-story.inverse {background: #dd7503}
.board-story.stage-projected.inverse {background-color:#777;}
.board-story.stage-developing.inverse {background-color:#D2322D;}
+14 -3
View File
@@ -242,9 +242,20 @@ $lang->project->orderList['id_desc'] = "ID Desc";
$lang->project->orderList['stage_asc'] = "Stage Asc";
$lang->project->orderList['stage_desc'] = "Stage Desc";
$lang->project->kanban = "Kanban";
$lang->project->printKanban = "Print Kanban";
$lang->project->bugList = "Bugs";
$lang->project->kanban = "Kanban";
$lang->project->kanbanSetting = "Kanban Setting";
$lang->project->resetKanban = "Reset Setting";
$lang->project->printKanban = "Print Kanban";
$lang->project->bugList = "Bugs";
$lang->project->kanbanHideCols = 'Kanban hidden has been closed and canceled columns';
$lang->project->kanbanShowOption = 'Display folding information';
$lang->project->kanbanColsColor = 'Custom color for Kanban column';
$lang->kanbanSetting = new stdclass();
$lang->kanbanSetting->noticeReset = 'Do you want to restore the Kanban default settings?';
$lang->kanbanSetting->optionList['0'] = 'Hidden';
$lang->kanbanSetting->optionList['1'] = 'Show';
$lang->printKanban = new stdclass();
$lang->printKanban->common = 'Print Kanban';
+14 -3
View File
@@ -242,9 +242,20 @@ $lang->project->orderList['id_desc'] = "需求ID倒序";
$lang->project->orderList['stage_asc'] = "需求阶段正序";
$lang->project->orderList['stage_desc'] = "需求阶段倒序";
$lang->project->kanban = "看板";
$lang->project->printKanban = "打印看板";
$lang->project->bugList = "Bug列表";
$lang->project->kanban = "看板";
$lang->project->kanbanSetting = "看板设置";
$lang->project->resetKanban = "恢复默认";
$lang->project->printKanban = "打印看板";
$lang->project->bugList = "Bug列表";
$lang->project->kanbanHideCols = '看板隐藏已关闭、已取消列';
$lang->project->kanbanShowOption = '显示折叠信息';
$lang->project->kanbanColsColor = '看板列自定义颜色';
$lang->kanbanSetting = new stdclass();
$lang->kanbanSetting->noticeReset = '是否恢复看板默认设置?';
$lang->kanbanSetting->optionList['0'] = '隐藏';
$lang->kanbanSetting->optionList['1'] = '显示';
$lang->printKanban = new stdclass();
$lang->printKanban->common = '看板打印';
+33
View File
@@ -2124,6 +2124,39 @@ class projectModel extends model
return json_decode($prevKanbans, true);
}
/**
* Get kanban setting.
*
* @param int $projectID
* @access public
* @return object
*/
public function getKanbanSetting($projectID)
{
$allCols = '1';
$showOption = '0';
if(isset($this->config->project->kanbanSetting->allCols))
{
$allColPairs = json_decode($this->config->project->kanbanSetting->allCols, true);
if(isset($allColPairs[$projectID])) $allCols = $allColPairs[$projectID];
}
if(isset($this->config->project->kanbanSetting->showOption))
{
$showOption = $this->config->project->kanbanSetting->showOption;
}
$colorList = $this->config->project->kanbanSetting->colorList;
if(!is_array($colorList)) $colorList = json_decode($colorList, true);
$kanbanSetting = new stdclass();
$kanbanSetting->allCols = $allCols;
$kanbanSetting->showOption = $showOption;
$kanbanSetting->colorList = $colorList;
return $kanbanSetting;
}
/**
* Build burn data.
*
@@ -0,0 +1,62 @@
<?php
/**
* The kanban setting 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/header.lite.html.php';?>
<div id='titlebar'>
<div class='heading'>
<strong><?php echo $lang->project->kanbanSetting;?></strong>
</div>
</div>
<form target='hiddenwin' method='post'>
<table class='table'>
<?php if(common::hasPriv('project', 'kanbanHideCols')):?>
<tr>
<th class='text-right'><?php echo $lang->project->kanbanHideCols?></th>
<td><?php echo html::radio('allCols', $lang->kanbanSetting->optionList, $allCols)?></td>
</tr>
<?php endif;?>
<tr>
<th class='w-180px text-right'><?php echo $lang->project->kanbanShowOption?></th>
<td><?php echo html::radio('showOption', $lang->kanbanSetting->optionList, $showOption)?></td>
</tr>
<?php if(common::hasPriv('project', 'kanbanColsColor')):?>
<tr>
<th class='text-right'><?php echo $lang->project->kanbanColsColor?></th>
<td>
<div class='row-table'>
<?php foreach($colorList as $status => $color):?>
<div class='col-table'>
<?php echo $lang->task->statusList[$status];?>
<input type='hidden' id='color<?php echo $status?>' name="colorList[<?php echo $status?>]" data-provide='colorpicker' data-wrapper='input-group-btn fix-border-right' data-pull-menu-right='false' data-update-text='#name' value='<?php echo $color;?>'>
</div>
<?php endforeach;?>
</div>
</td>
</tr>
<?php endif;?>
<tr>
<td colspan='2' class='text-center'>
<?php
echo html::submitButton();
echo html::a(inlink('ajaxResetKanban', "projectID=$projectID"), $lang->project->resetKanban, 'hiddenwin', "class='btn'");
?>
</td>
</tr>
</table>
</form>
<script>
$(function()
{
$('.col-table .colorpicker:last .dropdown-menu').addClass('pull-right');
})
</script>
<?php include '../../common/view/footer.lite.html.php';?>
+25 -8
View File
@@ -10,7 +10,16 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php include './taskheader.html.php';?>
<?php $taskCols = array('wait', 'doing', 'pause', 'done', 'cancel', 'closed'); ?>
<style>
<?php foreach($colorList as $status => $color):?>
<?php echo ".board-bug-$status, .board-task-$status {background: $color;}\n"?>
<?php endforeach?>
</style>
<?php
$taskCols = array('wait', 'doing', 'pause', 'done');
if($allCols) $taskCols = array('wait', 'doing', 'pause', 'done', 'cancel', 'closed');
$account = $this->app->user->account
?>
<div id='kanban'>
<table class='boards-layout table' id='kanbanHeader'>
<thead>
@@ -34,7 +43,15 @@
<?php endforeach;?>
<th class='col-<?php echo $endCol?>'><?php echo $lang->task->statusList[$endCol];?>
<div class='actions'>
<?php if(common::hasPriv('project', 'printKanban')) echo html::commonButton("<i class='icon-print'></i><span class='btn-text'> " . $lang->project->printKanban . '</span>', "id='printKanban' title='" . $lang->project->printKanban . "'", 'btn btn-sm btn-link');?>
<div class="dropdown">
<button type="button" class="btn btn-mini btn-link dropdown-toggle" data-toggle="dropdown">
<span class="icon-ellipsis-v"></span>
</button>
<ul class="dropdown-menu pull-right">
<?php echo '<li>' . html::a($this->createLink('project', 'ajaxKanbanSetting', "projectID=$projectID"), "<i class='icon-cog'></i> " . $lang->project->kanbanSetting, '', "class='iframe'") . '</li>';?>
<?php if(common::hasPriv('project', 'printKanban')) echo '<li>' . html::a('###', "<i class='icon-print'></i> " . $lang->project->printKanban, '', "id='printKanban' title='" . $lang->project->printKanban . "'") . '</li>';?>
</ul>
</div>
</div>
</th>
</tr>
@@ -58,7 +75,7 @@
<?php if($hasStory):?>
<td class='col-story'>
<?php if(!empty($story->id)):?>
<div class='board board-story stage-<?php echo $story->stage?><?php if($story->assignedTo == $this->app->user->account) echo ' inverse';?>' data-id='<?php echo $story->id?>'>
<div class='board board-story stage-<?php echo $story->stage?><?php if($showOption) echo ' show-info'?><?php if($story->assignedTo == $account) echo ' inverse';?>' data-id='<?php echo $story->id?>'>
<div class='board-title'>
<?php echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', 'class="kanbanFrame" title="' . $story->title . '"');?>
<div class='board-actions'>
@@ -67,7 +84,7 @@
<button type='button' class='btn btn-mini btn-link dropdown-toggle' data-toggle='dropdown'>
<span class='icon-ellipsis-v'></span>
</button>
<div class='dropdown-menu pull-right'>
<div class='dropdown-menu' style='left:-30px;width:80px'>
<?php
echo (common::hasPriv('task', 'create')) ? html::a($this->createLink('task', 'create', "projectID=$story->project&storyID=$story->story&moduleID=$story->module", '', true), $lang->project->wbs, '', "class='kanbanFrame'") : '';
echo (common::hasPriv('task', 'batchCreate')) ? html::a($this->createLink('task', 'batchCreate', "projectID=$story->project&storyID=$story->story&iframe=true", '', true), $lang->project->batchWBS, '', "class='kanbanFrame' data-width='95%'") : '';
@@ -93,7 +110,7 @@
<td class='col-droppable col-<?php echo $col?>' data-id='<?php echo $col?>'>
<?php if(!empty($story->tasks[$col])):?>
<?php foreach($story->tasks[$col] as $task):?>
<div class='board board-task board-task-<?php echo $col ?><?php if($task->assignedTo == $this->app->user->account) echo ' inverse';?>' data-id='<?php echo $task->id?>' id='task-<?php echo $task->id?>'>
<div class='board board-task board-task-<?php echo $col ?><?php if($showOption) echo ' show-info'?><?php if($task->assignedTo == $account) echo ' inverse';?>' data-id='<?php echo $task->id?>' id='task-<?php echo $task->id?>'>
<div class='board-title'>
<?php
if(isset($task->delay))
@@ -109,7 +126,7 @@
<button type='button' class='btn btn-mini btn-link dropdown-toggle' data-toggle='dropdown'>
<span class='icon-ellipsis-v'></span>
</button>
<div class='dropdown-menu pull-right'>
<div class='dropdown-menu' style='left:-20px'>
<?php
echo (common::hasPriv('task', 'assignTo') and taskModel::isClickable($task, 'assignTo')) ? html::a($this->createLink('task', 'assignTo', "projectID=$task->project&taskID=$task->id", '', 'true'), $lang->task->assignTo, '', "class='kanbanFrame'") : '';
echo (common::hasPriv('task', 'start') and taskModel::isClickable($task, 'start')) ? html::a($this->createLink('task', 'start', "taskID=$task->id", '', 'true'), $lang->task->start, '', "class='kanbanFrame'") : '';
@@ -140,7 +157,7 @@
<?php endif?>
<?php if(!empty($story->bugs[$col])):?>
<?php foreach($story->bugs[$col] as $bug):?>
<div class='board board-bug board-bug-<?php echo $col ?>' data-id='<?php echo $bug->id?>' id='bug-<?php echo $bug->id?>'>
<div class='board board-bug board-bug-<?php echo $col ?><?php if($showOption) echo ' show-info'?><?php if($bug->assignedTo == $account) echo ' inverse';?>' data-id='<?php echo $bug->id?>' id='bug-<?php echo $bug->id?>'>
<div class='board-title'>
<i class="icon-bug"></i>
<?php echo html::a($this->createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', 'class="kanbanFrame" title="' . $bug->title . '"');?>
@@ -150,7 +167,7 @@
<button type='button' class='btn btn-mini btn-link dropdown-toggle' data-toggle='dropdown'>
<span class='icon-ellipsis-v'></span>
</button>
<div class='dropdown-menu pull-right'>
<div class='dropdown-menu' style='left:-20px'>
<?php
echo (common::hasPriv('bug', 'assignTo') and bugModel::isClickable($bug, 'assignTo')) ? html::a($this->createLink('bug', 'assignTo', "bugID=$bug->id", '', 'true'), $lang->bug->assignTo, '', "class='kanbanFrame'") : '';
echo (common::hasPriv('bug', 'resolve') and bugModel::isClickable($bug, 'resolve')) ? html::a($this->createLink('bug', 'resolve', "bugID=$bug->id", '', 'true'), $lang->bug->resolve, '', "class='kanbanFrame'") : '';
+2 -2
View File
@@ -1362,9 +1362,9 @@ class taskModel extends model
foreach($tasks as $task)
{
$task = $this->processTask($task);
if($task->children) foreach($task->children as $child)
if(isset($task->children))
{
$task = $this->processTask($child);
foreach($task->children as $child) $task = $this->processTask($child);
}
}
return $tasks;
+1 -1
View File
@@ -186,7 +186,7 @@ class testreportModel extends model
*/
public function getBugInfo($tasks, $productIdList, $begin, $end, $builds)
{
$bugsByTask = $this->dao->select('*')->from(TABLE_BUG)->where('testtask')->in(array_keys($tasks))->andWhere('testtask')->ne(0)->andWhere('deleted')->eq(0)->fetchAll('id');
$bugsByTask = $this->dao->select('*')->from(TABLE_BUG)->where('testtask')->in(array_keys($tasks))->andWhere('testtask')->ne(0)->andWhere('`case`')->ne(0)->andWhere('deleted')->eq(0)->fetchAll('id');
$severityGroups = $statusGroups = $openedByGroups = $resolvedByGroups = $resolutionGroups = $moduleGroups = $typeGroups = array();
$resolvedBugs = 0;
foreach($bugsByTask as $bug)