* Finisht task #46666,#46668,#46659,#46658.

This commit is contained in:
tianshujie
2021-12-28 16:56:38 +08:00
parent 593cabd96c
commit 545438e452
9 changed files with 253 additions and 16 deletions
+5 -1
View File
@@ -155,7 +155,11 @@ $lang->kanban->error->mustBeInt = 'The WIPs must be positive integer.';
$lang->kanban->error->parentLimitNote = 'The WIPs in the parent column cannot be < the sum of the WIPs in the child column.';
$lang->kanban->error->childLimitNote = 'The sum of products in the child column cannot be > the number of products in the parent column.';
$lang->kanban->defaultColumn = array('wait', 'doing', 'done', 'close');
$lang->kanban->defaultColumn = array();
$lang->kanban->defaultColumn['wait'] = 'wait';
$lang->kanban->defaultColumn['doing'] = 'doing';
$lang->kanban->defaultColumn['done'] = 'done';
$lang->kanban->defaultColumn['closed'] = 'close';
$this->lang->kanban->laneTypeList = array();
$this->lang->kanban->laneTypeList['story'] = $lang->SRCommon;
+5 -1
View File
@@ -155,7 +155,11 @@ $lang->kanban->error->mustBeInt = '在制品数量必须是正整数。';
$lang->kanban->error->parentLimitNote = '父列的在制品数量不能小于子列在制品数量之和';
$lang->kanban->error->childLimitNote = '子列在制品数量之和不能大于父列的在制品数量';
$lang->kanban->defaultColumn = array('未开始', '进行中', '已完成', '已关闭');
$lang->kanban->defaultColumn = array();
$lang->kanban->defaultColumn['wait'] = '未开始';
$lang->kanban->defaultColumn['doing'] = '进行中';
$lang->kanban->defaultColumn['done'] = '已完成';
$lang->kanban->defaultColumn['closed'] = '已关闭';
$this->lang->kanban->laneTypeList = array();
$this->lang->kanban->laneTypeList['story'] = $lang->SRCommon;
+79
View File
@@ -517,6 +517,85 @@ class kanbanModel extends model
return $kanbanData;
}
/**
* Get plan kanban.
*
* @param object $product
* @param int $branchID
* @param string $orderBy
* @access public
* @return array
*/
public function getPlanKanban($product, $branchID = 0, $orderBy = 'id_desc')
{
$this->loadModel('branch');
$this->loadModel('productplan');
$kanbanData = new stdclass();
$lanes = array();
$columns = array();
$branches = array();
$colorIndex = 0;
$laneOrder = 1;
$planGroup = $this->productplan->getGroupByProduct($product->id, 'skipParent', 'object');
if($product->type == 'normal' or $branchID == BRANCH_MAIN)
{
$branches = array(BRANCH_MAIN => $this->lang->branch->main);
}
elseif($branchID == 'all')
{
$branches = $this->branch->getPairs($product->id);
}
elseif($branchID)
{
$branchName = $this->branch->getById($branchID);
$branches = array($branchID => $branchName);
}
foreach($branches as $branchID => $branchName)
{
$plans = isset($planGroup[$product->id][$branchID]) ? array_filter($planGroup[$product->id][$branchID]) : array();
$planList = array();
foreach($plans as $planID => $plan)
{
if(empty($plan)) continue;
if(!isset($planList[$plan->status])) $planList[$plan->status] = array();
$planList[$plan->status][] = $plan;
}
$lane = new stdclass();
$lane->id = $branchID;
$lane->type = 'branch';
$lane->name = $branchName;
$lane->color = $this->config->productplan->laneColorList[$colorIndex];
$lane->order = $laneOrder;
$lane->items = $planList;
$lanes[] = $lane;
$laneOrder += 1;
$colorIndex += 1;
if($colorIndex == count($this->config->productplan->laneColorList) + 1) $colorIndex = 0;
}
foreach($this->lang->kanban->defaultColumn as $columnType => $columnName)
{
$column = new stdclass();
$column->id = $columnType;
$column->type = $columnType;
$column->name = $columnName;
$columns[] = $column;
}
$kanbanData->id = 'plans';
$kanbanData->lanes = $lanes;
$kanbanData->columns = $columns;
return $kanbanData;
}
/**
* Get region by id.
*
+2
View File
@@ -8,3 +8,5 @@ $config->productplan->edit->requiredFields = 'title';
$config->productplan->editor = new stdclass();
$config->productplan->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
$config->productplan->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
$config->productplan->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
+29 -3
View File
@@ -236,8 +236,11 @@ class productplan extends control
* @access public
* @return void
*/
public function browse($productID = 0, $branch = 0, $browseType = 'all', $orderBy = 'begin_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1 )
public function browse($productID = 0, $branch = '', $browseType = 'all', $orderBy = 'begin_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1 )
{
$branchID = $branch === '' ? 'all' : $branch;
if(!$branch) $branch = 0;
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
@@ -251,9 +254,32 @@ class productplan extends control
$this->commonAction($productID, $branch);
$product = $this->product->getById($productID);
$productName = empty($product) ? '' : $product->name;
if($product->type != 'normal' and $viewType == 'bykanban')
if($viewType == 'bykanban')
{
$this->view->branches = array('all' => $this->lang->productplan->allAB) + $this->loadModel('branch')->getPairs($productID);
$branches = array();
$branchPairs = array();
$planCount = 0;
if($product->type == 'normal')
{
$branches = array(BRANCH_MAIN => $this->lang->branch->main);
}
else
{
$branches = $this->branch->getPairs($product->id);
}
$planGroup = $this->productplan->getGroupByProduct($product->id, 'skipParent', 'object');
foreach($branches as $id => $name)
{
$plans = isset($planGroup[$product->id][$id]) ? array_filter($planGroup[$product->id][$id]) : array();
$branchPairs[$id] = $name . ' ' . count($plans);
$planCount += count($plans);
}
$this->view->branches = array('all' => $this->lang->productplan->allAB . ' ' . $planCount) + $branchPairs;
$this->view->branchID = $branchID;
$this->view->planCount = $planCount;
$this->view->kanbanData = $this->loadModel('kanban')->getPlanKanban($product, $branchID, $orderBy);
}
$this->view->title = $productName . $this->lang->colon . $this->lang->productplan->browse;
+104
View File
@@ -43,6 +43,37 @@ $(function()
$.cookie('viewType', viewType, {expires:config.cookieLife, path:config.webRoot});
window.location.reload();
});
$('#branch').change(function()
{
var branchID = $(this).val();
var link = createLink('productplan', 'browse', "productID=" + productID + '&branch=' + branchID);
location.href = link;
});
if(viewType == 'bykanban')
{
$('#branch_chosen .chosen-single span').prepend('<i class="icon-delay"></i>');
$('#kanban').kanban(
{
data: kanbanData,
minColWidth: 290,
maxColWidth: 290,
itemRender: renderKanbanItem,
virtualize: true,
droppable:
{
target: findDropColumns,
finish: handleFinishDrop,
mouseButton: 'left'
}
});
$('#kanban').on('scroll', function()
{
$.zui.ContextMenu.hide();
});
}
});
$(document).on('click', 'td.content .more', function(e)
@@ -64,6 +95,79 @@ $(document).on('click', 'td.content .more', function(e)
}
});
/*
* Find drop columns
* @param {JQuery} $element Drag element
* @param {JQuery} $root Dnd root element
*/
function findDropColumns($element, $root)
{
var $col = $element.closest('.kanban-col');
var col = $col.data();
var lane = $col.closest('.kanban-lane').data();
var kanbanID = $root.data('id');
var kanbanRules = window.kanbanDropRules ? window.kanbanDropRules[kanbanID] : null;
if(!kanbanRules) return $root.find('.kanban-lane[data-id="' + lane.id + '"] .kanban-lane-col:not([data-type="project"],[data-type="' + col.type + '"])');
var colRules = kanbanRules[col.type];
var lane = $col.closest('.kanban-lane').data('lane');
return $root.find('.kanban-lane-col').filter(function()
{
if(!colRules) return false;
if(colRules === true) return true;
var $newCol = $(this);
var newCol = $newCol.data();
if(newCol.id === col.id) return false;
var $newLane = $newCol.closest('.kanban-lane');
var newLane = $newLane.data('lane');
return colRules.indexOf(newCol.type) > -1 && newLane.id === lane.id;
});
}
/**
* Handle finish drop task
* @param {Object} event Event object
* @returns {void}
*/
function handleFinishDrop(event)
{
var $card = $(event.element); // The drag card
var $dragCol = $card.closest('.kanban-lane-col');
var $dropCol = $(event.target);
/* Get d-n-d(drag and drop) infos 获取拖放操作相关信息 */
var card = $card.data('item');
var fromColType = $dragCol.data('type');
var toColType = $dropCol.data('type');
var kanbanID = $card.closest('.kanban').data('id');
changeCardColType(card, fromColType, toColType, kanbanID);
}
/**
* Change column type for a card
* @param {Object} card Card object
* @param {String} fromColType The column type before change
* @param {String} toColType The column type after change
* @param {String} kanbanID Kanban ID
*/
function changeCardColType(card, fromColType, toColType, kanbanID)
{
if(typeof card == 'undefined') return false;
}
/**
* The function for rendering kanban item
*/
function renderKanbanItem(item, $item)
{
var $title = $item.children('.title');
}
/**
* Get planID
*
+15 -7
View File
@@ -283,14 +283,15 @@ class productplanModel extends model
*
* @param string|array $products
* @param string $param skipParent|unexpired
* @param string $returnType pairs|object
* @access public
* @return array
*/
public function getGroupByProduct($products = '', $param = '')
public function getGroupByProduct($products = '', $param = '', $returnType = 'pairs')
{
$date = date('Y-m-d');
$param = strtolower($param);
$plans = $this->dao->select('id,title,parent,begin,end,product,branch')->from(TABLE_PRODUCTPLAN)
$plans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)
->where('deleted')->eq(0)
->beginIF($products)->andWhere('product')->in($products)->fi()
->beginIF(strpos($param, 'skipparent') !== false)->andWhere('parent')->ne(-1)->fi()
@@ -298,7 +299,7 @@ class productplanModel extends model
->orderBy('id_desc')
->fetchAll('id');
if(!empty($plans)) $plans = $this->reorder4Children($plans);
if(!empty($plans) and $returnType != 'object') $plans = $this->reorder4Children($plans);
$parentTitle = array();
$planGroup = array();
@@ -306,10 +307,17 @@ class productplanModel extends model
{
if(!isset($planGroup[$plan->product][$plan->branch])) $planGroup[$plan->product][$plan->branch] = array('' => '');
if($plan->parent == '-1') $parentTitle[$plan->id] = $plan->title;
if($plan->parent > 0 and isset($parentTitle[$plan->parent])) $plan->title = $parentTitle[$plan->parent] . ' /' . $plan->title;
$planGroup[$plan->product][$plan->branch][$plan->id] = $plan->title . " [{$plan->begin} ~ {$plan->end}]";
if($plan->begin == '2030-01-01' and $plan->end == '2030-01-01') $planGroup[$plan->product][$plan->branch][$plan->id] = $plan->title . ' ' . $this->lang->productplan->future;
if($returnType == 'object')
{
$planGroup[$plan->product][$plan->branch][$plan->id] = $plan;
}
else
{
if($plan->parent == '-1') $parentTitle[$plan->id] = $plan->title;
if($plan->parent > 0 and isset($parentTitle[$plan->parent])) $plan->title = $parentTitle[$plan->parent] . ' /' . $plan->title;
$planGroup[$plan->product][$plan->branch][$plan->id] = $plan->title . " [{$plan->begin} ~ {$plan->end}]";
if($plan->begin == '2030-01-01' and $plan->end == '2030-01-01') $planGroup[$plan->product][$plan->branch][$plan->id] = $plan->title . ' ' . $this->lang->productplan->future;
}
}
return $planGroup;
}
+1
View File
@@ -17,6 +17,7 @@
<?php js::set('noLinkedProject', $lang->productplan->noLinkedProject);?>
<?php js::set('enterProjectList', $lang->productplan->enterProjectList);?>
<?php js::set('projectNotEmpty', $lang->productplan->projectNotEmpty)?>
<?php js::set('viewType', $viewType);?>
<?php
if($viewType == 'bykanban')
{
@@ -10,24 +10,28 @@
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/kanban.html.php';?>
<style>
#allPlans {display: block; height: 25px; margin: 0 auto; text-align: center;}
#allPlans > i, #allPlans > span {display: inline-block; vertical-align: middle; line-height: 25px;}
#allPlans > i {color: #999;}
#branchBox {width: 100px; border-radius: 4px;}
#branchBox {width: 120px;}
#branch_chosen .icon-delay {padding-right: 10px; font-size: 15px;}
#kanbanContainer {padding-bottom: 0; margin-bottom: 0;}
</style>
<?php js::set('kanbanData', $kanbanData);?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php if($product->type == 'normal'):?>
<div id='allPlans'>
<i class='icon icon-delay'></i>
<span><?php echo $lang->productplan->all . ' ' . $pager->recTotal;?></span>
<span><?php echo $lang->productplan->all . ' ' . $planCount;?></span>
</div>
<?php else:?>
<div id='branchBox'>
<?php echo html::select('branch', $branches, $branch, "class='form-control chosen control-branch'");?>
<?php endif;?>
<?php echo html::select('branch', $branches, $branchID, "class='form-control chosen control-branch'");?>
</div>
<?php endif;?>
</div>
<div class="btn-toolbar pull-right">
<div class="btn-group panel-actions">
@@ -39,3 +43,8 @@
<?php endif;?>
</div>
</div>
<div class='panel' id='kanbanContainer'>
<div class='panel-body'>
<div id='kanban'></div>
</div>
</div>