Merge branch 'sprint/182_tianshujie_47352' into 'kanban'
* Finish task #47352. See merge request easycorp/zentaopms!1369
This commit is contained in:
@@ -72,14 +72,14 @@ foreach($executions as $projectID => $projectExecutions)
|
||||
|
||||
foreach($projectExecutions as $index => $execution)
|
||||
{
|
||||
$kanbanLink = $this->createLink('execution', 'kanban', "executionID=%s");
|
||||
$taskLink = $this->createLink('execution', 'task', "executionID=%s");
|
||||
if($execution->type != 'kanban' and $link == $kanbanLink) $link = $taskLink;
|
||||
if($execution->type == 'kanban' and $link != $kanbanLink) $link = $kanbanLink;
|
||||
|
||||
$selected = $execution->id == $executionID ? 'selected' : '';
|
||||
if($execution->status != 'done' and $execution->status != 'closed' and ($execution->PM == $this->app->user->account or isset($execution->teams[$this->app->user->account])))
|
||||
{
|
||||
$kanbanLink = $this->createLink('execution', 'kanban', "executionID=%s");
|
||||
$taskLink = $this->createLink('execution', 'task', "executionID=%s");
|
||||
if($execution->type != 'kanban' and $link == $kanbanLink) $link = $taskLink;
|
||||
if($execution->type == 'kanban' and $link != $kanbanLink) $link = $kanbanLink;
|
||||
|
||||
$myExecutionsHtml .= '<li>' . html::a(sprintf($link, $execution->id), $execution->name, '', "class='$selected executionName' title='{$execution->name}' data-key='" . zget($executionsPinYin, $execution->name, '') . "' data-app='{$this->app->tab}'") . '</li>';
|
||||
|
||||
if($selected == 'selected') $tabActive = 'myExecution';
|
||||
|
||||
@@ -139,7 +139,7 @@ js::set('hasTaskButton', $hasTaskButton);
|
||||
<button class="btn btn-link action" type="button" data-toggle="dropdown"><i class="icon icon-ellipsis-v"></i></button>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<?php if($canEditRegion) echo '<li>' . html::a(helper::createLink('kanban', 'editRegion', "regionID={$region->id}", '', 1), '<i class="icon icon-edit"></i>' . $this->lang->kanban->editRegion, '', 'class="iframe" data-toggle="modal" data-width="600px"') . '</li>';?>
|
||||
<?php if($canCreateLane) echo '<li>' . html::a(helper::createLink('kanban', 'createLane', "executionID={$execution->id}®ionID={$region->id}", '', 1), '<i class="icon icon-plus"></i>' . $this->lang->kanban->createLane, '', "class='iframe'") . '</li>';?>
|
||||
<?php if($canCreateLane) echo '<li>' . html::a(helper::createLink('kanban', 'createLane', "executionID={$execution->id}®ionID={$region->id}&from=execution", '', 1), '<i class="icon icon-plus"></i>' . $this->lang->kanban->createLane, '', "class='iframe'") . '</li>';?>
|
||||
<?php if($canDeleteRegion and count($regions) > 1) echo '<li>' . html::a(helper::createLink('kanban', 'deleteRegion', "regionID={$region->id}"), '<i class="icon icon-trash"></i>' . $this->lang->kanban->deleteRegion, "hiddenwin") . '</li>';?>
|
||||
</ul>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -417,10 +417,11 @@ class kanban extends control
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param int $regionID
|
||||
* @param string $from kanban|execution
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createLane($kanbanID, $regionID)
|
||||
public function createLane($kanbanID, $regionID, $from = 'kanban')
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
@@ -431,8 +432,12 @@ class kanban extends control
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
|
||||
}
|
||||
|
||||
$this->view->lanes = $this->kanban->getLanePairsByRegion($regionID);
|
||||
$this->display();
|
||||
$this->view->lanes = $this->kanban->getLanePairsByRegion($regionID, $from == 'kanban' ? 'all' : 'story');
|
||||
$this->view->from = $from;
|
||||
$this->view->regionID = $regionID;
|
||||
|
||||
if($from == 'kanban') $this->display();
|
||||
if($from == 'execution') $this->display('kanban', 'createexeclane');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1132,4 +1137,20 @@ class kanban extends control
|
||||
$this->view->method = $methodName;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get lanes by region id.
|
||||
*
|
||||
* @param int $regionID
|
||||
* @param string $type all|story|task|bug
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetLanes($regionID, $type = 'all')
|
||||
{
|
||||
$lanes = $this->kanban->getLanePairsByRegion($regionID, $type);
|
||||
|
||||
if(empty($lanes)) return;
|
||||
return print(html::select('otherLane', $lanes, '', "class='form-control'"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,3 @@ $(document).ready(function()
|
||||
$('#otherLane').parents('tr').toggle($(this).val() == 'sameAsOther');
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
+45
-28
@@ -1026,35 +1026,52 @@ $(function()
|
||||
*/
|
||||
function resetRegionHeight(fold)
|
||||
{
|
||||
if(Object.keys(regions).length == 1)
|
||||
var regionCount = 0;
|
||||
if($.isEmptyObject(regions)) return false;
|
||||
for(var i in regions)
|
||||
{
|
||||
var regionID = Object.keys(regions)[0];
|
||||
var region = regions[regionID].groups;
|
||||
if(Object.keys(region).length == 1)
|
||||
{
|
||||
var group = region[0];
|
||||
if(Object.keys(group.lanes).length == 1)
|
||||
{
|
||||
var regionHeaderHeight = $('.region-header').outerHeight();
|
||||
if(fold == 'open')
|
||||
{
|
||||
var windowHeight = $(window).height();
|
||||
var headerHeight = $('#mainHeader').outerHeight();
|
||||
var mainPadding = $('#main').css('padding-top');
|
||||
var panelBorder = $('.panel').css('border-top-width');
|
||||
var bodyPadding = $('.panel-body').css('padding-top');
|
||||
var height = windowHeight - (parseInt(mainPadding) * 2) - (parseInt(bodyPadding) * 2) - headerHeight - (parseInt(panelBorder) * 2);
|
||||
var regionPadding = $('.kanban').css('padding-bottom');
|
||||
var columnHeight = $('.kanban-header').outerHeight();
|
||||
regionCount += 1;
|
||||
if(regionCount > 1) return false;
|
||||
}
|
||||
|
||||
$('.region').css('height', height);
|
||||
$('.kanban-lane').css('height', height - regionHeaderHeight - parseInt(regionPadding) - columnHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
$('.region').css('height', regionHeaderHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
var regionID = Object.keys(regions)[0];
|
||||
var region = regions[regionID].groups;
|
||||
var groupCount = 0;
|
||||
|
||||
if($.isEmptyObject(region)) return false;
|
||||
for(var j in region)
|
||||
{
|
||||
groupCount += 1;
|
||||
if(groupCount > 1) return false;
|
||||
}
|
||||
|
||||
var group = region[0];
|
||||
var laneCount = 0;
|
||||
|
||||
if($.isEmptyObject(group.lanes)) return false;
|
||||
for(var h in group.lanes)
|
||||
{
|
||||
laneCount += 1;
|
||||
if(laneCount > 1) return false;
|
||||
}
|
||||
|
||||
var regionHeaderHeight = $('.region-header').outerHeight();
|
||||
if(fold == 'open')
|
||||
{
|
||||
var windowHeight = $(window).height();
|
||||
var headerHeight = $('#mainHeader').outerHeight();
|
||||
var mainPadding = $('#main').css('padding-top');
|
||||
var panelBorder = $('.panel').css('border-top-width');
|
||||
var bodyPadding = $('.panel-body').css('padding-top');
|
||||
var height = windowHeight - (parseInt(mainPadding) * 2) - (parseInt(bodyPadding) * 2) - headerHeight - (parseInt(panelBorder) * 2);
|
||||
var regionPadding = $('.kanban').css('padding-bottom');
|
||||
var columnHeight = $('.kanban-header').outerHeight();
|
||||
|
||||
$('.region').css('height', height);
|
||||
$('.kanban-lane').css('height', height - regionHeaderHeight - parseInt(regionPadding) - columnHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
$('.region').css('height', regionHeaderHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,7 @@ $lang->kanbanlane->default = 'Default Lane';
|
||||
$lang->kanbanlane->column = 'Lane Kanban Column';
|
||||
$lang->kanbanlane->otherlane = 'Select Existed Lane';
|
||||
$lang->kanbanlane->color = 'Lane Color';
|
||||
$lang->kanbanlane->WIPType = 'Lane WIP Type';
|
||||
|
||||
$lang->kanbanlane->confirmDelete = 'Are you sure to delete this lane? After deleting the lane, all data (columns and cards) in the lane will also be deleted.';
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@ $lang->kanbanlane->default = '默认泳道';
|
||||
$lang->kanbanlane->column = '泳道看板列';
|
||||
$lang->kanbanlane->otherlane = '选择共享看板列的泳道';
|
||||
$lang->kanbanlane->color = '泳道颜色';
|
||||
$lang->kanbanlane->WIPType = '泳道在制品类型';
|
||||
|
||||
$lang->kanbanlane->confirmDelete = '您确认删除该泳道吗?删除泳道后,该泳道中所有数据(列、卡片)也会被删除。';
|
||||
|
||||
|
||||
+18
-10
@@ -145,7 +145,7 @@ class kanbanModel extends model
|
||||
$copyColumn->parent = $parentColumns[$copyColumn->parent];
|
||||
}
|
||||
|
||||
$parentColumnID = $this->createColumn($regionID, $copyColumn);
|
||||
$parentColumnID = $this->createColumn($regionID, $copyColumn, 0, 0, $from);
|
||||
|
||||
if($copyColumn->parent < 0) $parentColumns[$copyColumnID] = $parentColumnID;
|
||||
if(dao::isError()) return false;
|
||||
@@ -230,10 +230,11 @@ class kanbanModel extends model
|
||||
* @param object $column
|
||||
* @param int $order
|
||||
* @param int $parent
|
||||
* @param string $from kanban|execution
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createColumn($regionID, $column = null, $order = 0, $parent = 0)
|
||||
public function createColumn($regionID, $column = null, $order = 0, $parent = 0, $from = 'kanban')
|
||||
{
|
||||
if(empty($column))
|
||||
{
|
||||
@@ -312,7 +313,7 @@ class kanbanModel extends model
|
||||
|
||||
$columnID = $this->dao->lastInsertID();
|
||||
|
||||
$this->dao->update(TABLE_KANBANCOLUMN)->set('type')->eq("column{$columnID}")->where('id')->eq($columnID)->exec();
|
||||
if($from == 'kanban') $this->dao->update(TABLE_KANBANCOLUMN)->set('type')->eq("column{$columnID}")->where('id')->eq($columnID)->exec();
|
||||
|
||||
/* Add kanban cell. */
|
||||
$lanes = $this->dao->select('id')->from(TABLE_KANBANLANE)->where('`group`')->eq($column->group)->fetchPairs();
|
||||
@@ -1254,14 +1255,16 @@ class kanbanModel extends model
|
||||
* Get lane pairs by region id.
|
||||
*
|
||||
* @param array $regionID
|
||||
* @param string $type all|story|task|bug|common
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLanePairsByRegion($regionID)
|
||||
public function getLanePairsByRegion($regionID, $type = 'all')
|
||||
{
|
||||
return $this->dao->select('id, name')->from(TABLE_KANBANLANE)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('region')->eq($regionID)
|
||||
->beginIF($type != 'all')->andWhere('type')->eq($type)->fi()
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
@@ -1285,11 +1288,14 @@ class kanbanModel extends model
|
||||
->add('region', $regionID)
|
||||
->add('order', $maxOrder ? $maxOrder + 1 : 1)
|
||||
->add('lastEditedTime', helper::now())
|
||||
->add('type', 'common')
|
||||
->setIF(isset($this->post->laneType), 'execution', $kanbanID)
|
||||
->trim('name')
|
||||
->setDefault('color', '#7ec5ff')
|
||||
->remove('laneType')
|
||||
->get();
|
||||
|
||||
$lane->type = isset($_POST['laneType']) ? $_POST['laneType'] : 'common';
|
||||
|
||||
$mode = zget($lane, 'mode', '');
|
||||
if($mode == 'sameAsOther')
|
||||
{
|
||||
@@ -1298,11 +1304,12 @@ class kanbanModel extends model
|
||||
}
|
||||
elseif($mode == 'independent')
|
||||
{
|
||||
$groupID = $this->createGroup($kanbanID, $regionID);
|
||||
$kanban = $this->getByID($kanbanID);
|
||||
$this->createDefaultColumns($kanban, $regionID, $groupID);
|
||||
|
||||
$lane->group = $groupID;
|
||||
$lane->group = $this->createGroup($kanbanID, $regionID);
|
||||
if($lane->type == 'common')
|
||||
{
|
||||
$kanban = $this->getByID($kanbanID);
|
||||
$this->createDefaultColumns($kanban, $regionID, $lane->group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1313,6 +1320,7 @@ class kanbanModel extends model
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$laneID = $this->dao->lastInsertID();
|
||||
if($lane->type != 'common' and $mode == 'independent') $this->createRDColumn($regionID, $lane->group, $laneID, $lane->type);
|
||||
return $laneID;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* The createexeclane file of kanban module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Shujie Tian <tianshujie@easycorp.ltd>
|
||||
* @package kanban
|
||||
* @version $Id: createexeclane.html.php 935 2022-01-12 17:22:24Z $
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php js::set('colorList',$config->kanban->laneColorList);?>
|
||||
<?php js::set('regionID', $regionID);?>
|
||||
<?php js::set('lanes', $lanes);?>
|
||||
<style>
|
||||
.table-form>tbody>tr>th {width: 150px;}
|
||||
#otherLane_chosen {top: -8px;}
|
||||
#laneTypeBox {line-height: 16px;}
|
||||
.margin-bottom {margin-bottom: -6px;}
|
||||
</style>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
<?php echo $lang->kanban->createLane;?>
|
||||
</h2>
|
||||
</div>
|
||||
<form class='load-indicator main-form form-ajax' method='post' enctype='multipart/form-data'>
|
||||
<table class='table table-form'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->name;?></th>
|
||||
<td colspan='3'>
|
||||
<div class='required required-wrapper'></div>
|
||||
<?php echo html::input('name', '', "class='form-control'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->WIPType;?></th>
|
||||
<td id='laneTypeBox'><?php echo html::radio('laneType', $lang->kanban->laneTypeList, 'story');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->column;?></th>
|
||||
<?php $mode = empty($lanes) ? 'independent' : 'sameAsOther';?>
|
||||
<td id='modeBox'><?php echo html::radio('mode', $lang->kanbanlane->modeList, $mode, '', 'block');?></td>
|
||||
<td id='laneBox' <?php if(empty($lanes)) echo 'hidden';?>><?php echo html::select('otherLane', $lanes, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->color;?></th>
|
||||
<td colspan='3'>
|
||||
<div id='color-picker'></div>
|
||||
<?php echo html::input('color', '#7ec5ff', "class='hidden'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='text-center form-actions' colspan='4'>
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::commonButton($lang->cancel, "data-dismiss='modal'", 'btn btn-wide');?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function()
|
||||
{
|
||||
initColorPicker();
|
||||
if($.isEmptyObject(lanes))
|
||||
{
|
||||
$('#modesameAsOther').closest('div').addClass('hidden');
|
||||
$('#laneBox').addClass('hidden');
|
||||
$('#modeindependent').attr('checked', 'checked');
|
||||
$('#modeindependent').closest('div').addClass('margin-bottom');
|
||||
}
|
||||
|
||||
$('input[name=mode]').change(function()
|
||||
{
|
||||
$('#otherLane').parents('td').toggle($(this).val() == 'sameAsOther');
|
||||
if($(this).val() == 'sameAsOther') $('#laneBox').removeClass('hidden');
|
||||
});
|
||||
|
||||
$('input[name=laneType]').change(function()
|
||||
{
|
||||
var laneType = $(this).val();
|
||||
var link = createLink('kanban', 'ajaxGetLanes', 'regionID=' + regionID + '&type=' + laneType);
|
||||
|
||||
$.get(link, function(lanes)
|
||||
{
|
||||
if(lanes)
|
||||
{
|
||||
$('#modesameAsOther').parents('div').removeClass('hidden');
|
||||
$('#otherLane').replaceWith(lanes);
|
||||
$('#otherLane_chosen').remove();
|
||||
$('#otherLane').chosen();
|
||||
$('#modeindependent').closest('div').removeClass('margin-bottom');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#modesameAsOther').closest('div').addClass('hidden');
|
||||
$('#laneBox').addClass('hidden');
|
||||
$('#modeindependent').attr('checked', 'checked');
|
||||
$('#modeindependent').closest('div').addClass('margin-bottom');
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
Reference in New Issue
Block a user