* Finish task #46672.

This commit is contained in:
tianshujie
2021-12-30 11:02:42 +08:00
parent 137281f8fb
commit 08723126ea
6 changed files with 144 additions and 45 deletions
+7 -2
View File
@@ -537,7 +537,7 @@ class kanbanModel extends model
$branches = array();
$colorIndex = 0;
$laneOrder = 1;
$cardActions = array('view');
$cardActions = array('view', 'createExecution', 'linkStory', 'linkBug', 'edit', 'start', 'finish', 'close', 'activate');
if($product->type == 'normal')
{
@@ -573,7 +573,12 @@ class kanbanModel extends model
$plan->actions = array();
foreach($cardActions as $action)
{
if(common::hasPriv('productplan', $action)) $plan->actions[] = $action;
if($action == 'createExecution')
{
if(common::hasPriv('execution', 'create')) $plan->actions[] = $action;
continue;
}
if($this->productplan->isClickable($plan, $action)) $plan->actions[] = $action;
}
$planList[$plan->status][] = $plan;
}
+18 -13
View File
@@ -252,8 +252,12 @@ class productplan extends control
$viewType = $this->cookie->viewType ? $this->cookie->viewType : 'list';
$this->commonAction($productID, $branch);
$product = $this->product->getById($productID);
$productName = empty($product) ? '' : $product->name;
$product = $this->product->getById($productID);
$productName = empty($product) ? '' : $product->name;
$branchList = $this->branch->getList($productID, 0, 'all');
$branchStatusList = array();
foreach($branchList as $productBranch) $branchStatusList[$productBranch->id] = $productBranch->status;
if($viewType == 'kanban')
{
$branches = array();
@@ -285,17 +289,18 @@ class productplan extends control
$this->view->kanbanData = $this->loadModel('kanban')->getPlanKanban($product, $branchID, $planGroup);
}
$this->view->title = $productName . $this->lang->colon . $this->lang->productplan->browse;
$this->view->position[] = $this->lang->productplan->browse;
$this->view->productID = $productID;
$this->view->branch = $branch;
$this->view->browseType = $browseType;
$this->view->viewType = $viewType;
$this->view->orderBy = $orderBy;
$this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort);
$this->view->pager = $pager;
$this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch);
$this->view->statusList = $this->lang->productplan->featureBar['browse'];
$this->view->title = $productName . $this->lang->colon . $this->lang->productplan->browse;
$this->view->position[] = $this->lang->productplan->browse;
$this->view->productID = $productID;
$this->view->branch = $branch;
$this->view->branchStatusList = $branchStatusList;
$this->view->browseType = $browseType;
$this->view->viewType = $viewType;
$this->view->orderBy = $orderBy;
$this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort);
$this->view->pager = $pager;
$this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch);
$this->view->statusList = $this->lang->productplan->featureBar['browse'];
$this->display();
}
+86 -1
View File
@@ -75,9 +75,94 @@ $(function()
{
$.zui.ContextMenu.hide();
});
/* Init contextmenu */
$('#kanban').on('click', '[data-contextmenu]', function(event)
{
var $trigger = $(this);
var menuType = $trigger.data('contextmenu');
var menuCreator = window.menuCreators[menuType];
if(!menuCreator) return;
var options = $.extend({event: event, $trigger: $trigger}, $trigger.data());
var items = menuCreator(options);
if(!items || !items.length) return;
$.zui.ContextMenu.show(items, items.$options || {event: event});
});
}
});
/* Define menu creators */
window.menuCreators =
{
card: createCardMenu
};
/**
* Create card menu.
*
* @param object $options
* @access public
* @return array
*/
function createCardMenu(options)
{
var card = options.$trigger.closest('.kanban-item').data('item');
var privs = card.actions;
if(!privs.length) return [];
var items = [];
if(privs.includes('createExecution'))
{
var className = '';
var executionLink = systemMode == 'new' ? '#projects' : createLink('execution', 'create', "projectID=0&executionID=0&copyExecutionID=0&plan=" + card.id + "&confirm=no&productID=" + productID);
var today = new Date();
var end = $.zui.createDate(card.end);
if(end.toLocaleDateString() < today.toLocaleDateString() && (card.status == 'wait' || card.status == 'doing'))
{
className = 'disabled';
}
else if(product.type != 'normal')
{
var branchStatus = branchStatusList[card.branch];
if(branchStatus == 'closed') className = 'disabled';
}
if(systemMode == 'new')
{
items.push({label: productplanLang.createExecution, icon: 'plus', url: executionLink, className: className, attrs: {'data-toggle': 'modal', 'onclick': 'getPlanID(this,' + card.branch + ')', 'data-id': card.id}});
}
else
{
items.push({label: productplanLang.createExecution, icon: 'plus', url: executionLink, className: className});
}
}
if(privs.includes('linkStory')) items.push({label: productplanLang.linkStory, icon: 'link', url: createLink('productplan', 'view', "planID=" + card.id + "&type=story&orderBy=id_desc&link=true")});
if(privs.includes('linkBug')) items.push({label: productplanLang.linkBug, icon: 'bug', url: createLink('productplan', 'view', "planID=" + card.id + "&type=bug&orderBy=id_desc&link=true")});
if(privs.includes('edit')) items.push({label: productplanLang.edit, icon: 'edit', url: createLink('productplan', 'edit', "planID=" + card.id)});
if(privs.includes('start'))
{
if(card.begin == '2030-01-01' || card.end == '2030-01-01')
{
items.push({label: productplanLang.start, icon: 'start', url: createLink('productplan', 'start', "planID=" + card.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-id': card.id, 'data-width': '550px'}});
}
else
{
items.push({label: productplanLang.start, icon: 'start', url: createLink('productplan', 'start', "planID=" + card.id), attrs: {'target': 'hiddenwin'}});
}
}
if(privs.includes('finish')) items.push({label: productplanLang.finish, icon: 'checked', url: createLink('productplan', 'finish', "planID=" + card.id), attrs: {'target': 'hiddenwin'}});
if(privs.includes('close')) items.push({label: productplanLang.close, icon: 'off', url: createLink('productplan', 'close', "planID=" + card.id), attrs: {'target': 'hiddenwin'}});
if(privs.includes('activate')) items.push({label: productplanLang.activate, icon: 'magic', url: createLink('productplan', 'activate', "planID=" + card.id), attrs: {'target': 'hiddenwin'}});
var bounds = options.$trigger[0].getBoundingClientRect();
items.$options = {x: bounds.right, y: bounds.top};
return items;
}
$(document).on('click', 'td.content .more', function(e)
{
var $toggle = $(this);
@@ -168,7 +253,7 @@ function changeCardColType(card, fromColType, toColType, kanbanID)
function renderKanbanItem(item, $item)
{
var privs = item.actions;
var printMoreBtn = privs.includes('view');
var printMoreBtn = (privs.includes('createExecution') || privs.includes('linkStory') || privs.includes('linkBug') || privs.includes('edit') || privs.includes('start') || privs.includes('finish') || privs.includes('close') || privs.includes('activate'));
/* Output header information. */
var $header = $item.children('.header');
+31
View File
@@ -18,6 +18,9 @@
<?php js::set('enterProjectList', $lang->productplan->enterProjectList);?>
<?php js::set('projectNotEmpty', $lang->productplan->projectNotEmpty)?>
<?php js::set('viewType', $viewType);?>
<?php js::set('product', $product);?>
<?php js::set('systemMode', $config->systemMode);?>
<?php js::set('branchStatusList', $branchStatusList);?>
<?php
if($viewType == 'kanban')
{
@@ -28,4 +31,32 @@ else
include 'browsebylist.html.php';
}
?>
<div class="modal fade" id="projects">
<div class="modal-dialog mw-500px">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?php echo $lang->productplan->selectProjects;?></h4>
</div>
<div class="modal-body">
<table class='table table-form'>
<tr>
<th><?php echo $lang->productplan->project?></th>
<td><?php echo html::select('project', $projects, '', "class='form-control chosen'");?></td>
</tr>
<tr class='tips hidden'>
<th></th>
<td><span class='text-red'><?php echo $lang->productplan->noLinkedProject;?></span></td>
</tr>
<tr>
<td colspan='2' class='text-center'>
<?php echo html::hidden('planID', '');?>
<?php echo html::commonButton($lang->productplan->nextStep, "id='createExecutionButton'", 'btn btn-primary btn-wide');?>
<?php echo html::commonButton($lang->cancel, "data-dismiss='modal'", 'btn btn-default btn-wide');?>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
@@ -30,6 +30,7 @@
.kanban-card .dateBox {padding-top: 22px;}
.kanban-card .desc {overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #838a9d; padding-top: 5px;}
.kanban-card .actions > a {display: block; float: left; width: 20px; height: 20px; line-height: 20px; text-align: center; border-radius: 4px; opacity: .7;}
.dropdown-menu > li > .disabled {pointer-events: none; color: #838a9d;}
</style>
<?php js::set('kanbanData', $kanbanData);?>
<?php js::set('productplanLang', $lang->productplan);?>
+1 -29
View File
@@ -163,7 +163,7 @@
if($product->type != 'normal')
{
$branchStatus = $this->branch->getByID($plan->branch, 0, 'status');
$branchStatus = isset($branchStatusList[$plan->branch]) ? $branchStatusList[$plan->branch] : '';
if($branchStatus == 'closed') $disabled = 'disabled';
}
@@ -214,31 +214,3 @@
</form>
<?php endif;?>
</div>
<div class="modal fade" id="projects">
<div class="modal-dialog mw-500px">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><?php echo $lang->productplan->selectProjects;?></h4>
</div>
<div class="modal-body">
<table class='table table-form'>
<tr>
<th><?php echo $lang->productplan->project?></th>
<td><?php echo html::select('project', $projects, '', "class='form-control chosen'");?></td>
</tr>
<tr class='tips hidden'>
<th></th>
<td><span class='text-red'><?php echo $lang->productplan->noLinkedProject;?></span></td>
</tr>
<tr>
<td colspan='2' class='text-center'>
<?php echo html::hidden('planID', '');?>
<?php echo html::commonButton($lang->productplan->nextStep, "id='createExecutionButton'", 'btn btn-primary btn-wide');?>
<?php echo html::commonButton($lang->cancel, "data-dismiss='modal'", 'btn btn-default btn-wide');?>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>