Merge branch 'sprint/182_tianshujie_47352' into 'kanban'

* Finish task #47352.

See merge request easycorp/zentaopms!1369
This commit is contained in:
孙广明
2022-01-13 01:47:50 +00:00
9 changed files with 206 additions and 48 deletions
@@ -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';
+1 -1
View File
@@ -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}&regionID={$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}&regionID={$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;?>
+24 -3
View File
@@ -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'"));
}
}
-1
View File
@@ -7,4 +7,3 @@ $(document).ready(function()
$('#otherLane').parents('tr').toggle($(this).val() == 'sameAsOther');
});
})
+45 -28
View File
@@ -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);
}
}
+1
View File
@@ -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.';
+1
View File
@@ -248,6 +248,7 @@ $lang->kanbanlane->default = '默认泳道';
$lang->kanbanlane->column = '泳道看板列';
$lang->kanbanlane->otherlane = '选择共享看板列的泳道';
$lang->kanbanlane->color = '泳道颜色';
$lang->kanbanlane->WIPType = '泳道在制品类型';
$lang->kanbanlane->confirmDelete = '您确认删除该泳道吗?删除泳道后,该泳道中所有数据(列、卡片)也会被删除。';
+18 -10
View File
@@ -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;
}
+111
View File
@@ -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';?>