Merge branch 'sprint/177_zhengrunyu_45882' into kanban
This commit is contained in:
@@ -4,6 +4,7 @@ $config->kanban = new stdclass();
|
||||
|
||||
$config->kanban->require = new stdclass();
|
||||
$config->kanban->require->createregion = 'name';
|
||||
$config->kanban->require->createlane = 'name';
|
||||
|
||||
$config->kanban->setwip = new stdclass();
|
||||
$config->kanban->setlane = new stdclass();
|
||||
@@ -83,4 +84,5 @@ $config->kanban->taskColumnStatusList['pause'] = 'pause';
|
||||
$config->kanban->taskColumnStatusList['canceled'] = 'cancel';
|
||||
$config->kanban->taskColumnStatusList['closed'] = 'closed';
|
||||
|
||||
$config->kanban->laneColorList = array('#7ec5ff', '#333', '#2b529c', '#e48600', '#d2323d', '#229f24', '#777', '#d2691e', '#008b8b', '#2e8b57', '#4169e1', '#4b0082', '#fa8072', '#ba55d3', '#2e8b57', '#6b8e23');
|
||||
$config->kanban->laneColorList = array('#7ec5ff', '#333', '#2b529c', '#e48600', '#d2323d', '#229f24', '#777', '#d2691e', '#008b8b', '#2e8b57', '#4169e1', '#4b0082', '#fa8072', '#ba55d3', '#2e8b57', '#6b8e23');
|
||||
$config->kanban->columnColorList = array('#333', '#2b519c', '#e48610', '#d2313d', '#2a9f23', '#777', '#d2691e', '#2e8b8b', '#2f8b58', '#4168e0', '#4b0082', '#f58072', '#ba55d3', '#6a8e22');
|
||||
|
||||
@@ -194,6 +194,29 @@ class kanban extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a lane for a kanban.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param int $regionID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createLane($kanbanID, $regionID)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$laneID = $this->kanban->createLane($kanbanID, $regionID, $lane = null);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'callback' => 'closeModalAndUpdateKanban', 'callback_params' => $regionID));
|
||||
}
|
||||
|
||||
$this->view->lanes = $this->kanban->getLanePairsByRegion($regionID);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set WIP.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.color-picker-item {width: 20px; height: 20px; margin-right: 10px; border-radius: 50% 50%; float: left; cursor: pointer; text-align: center; line-height: 20px;}
|
||||
.color-picker-item > .icon {color: #fff; display: none}
|
||||
.checked > .icon {display: inline-block;}
|
||||
|
||||
@@ -33,3 +33,34 @@ function setMailto(field, value)
|
||||
$('#team').chosen();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize custom color selector.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function initColorPicker()
|
||||
{
|
||||
var colorList = ['#272E33', '#3DC6FD', '#2B529C', '#E48600', '#D2323D', '#229F24', '#777777', '#D2691E', '#008B8B', '#2E8B57', '#4169E1', '#4B0082', '#FA8072', '#BA55D3', '#6B8E23'];
|
||||
|
||||
var selectedColor = $('input[name=color]').val();
|
||||
if(selectedColor && $.inArray(selectedColor.toUpperCase(), colorList) == -1) colorList.unshift(selectedColor);
|
||||
colorList.forEach(function(color, index)
|
||||
{
|
||||
var itemClass = color.toUpperCase() == $('input[name=color]').val().toUpperCase() ? 'color-picker-item checked' : 'color-picker-item';
|
||||
var colorItem = "<div class='" + itemClass + "' data-color='" + color + "' style='background: " + color + "'>";
|
||||
colorItem += "<i class='icon icon-check'></i>";
|
||||
colorItem += "</div>";
|
||||
$('#color-picker').append(colorItem);
|
||||
});
|
||||
|
||||
$('.color-picker-item').click(function()
|
||||
{
|
||||
var color = $(this).attr('data-color');
|
||||
$('input[name=color]').val(color);
|
||||
$(this).addClass('checked');
|
||||
$(this).siblings().removeClass('checked');
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
initColorPicker();
|
||||
|
||||
$('input[name=mode]').change(function()
|
||||
{
|
||||
$('#otherLane').parents('tr').toggle($(this).val() == 'sameAsOther');
|
||||
});
|
||||
})
|
||||
|
||||
@@ -624,15 +624,15 @@ function createColumnMenu(options)
|
||||
if(!privs.length) return [];
|
||||
|
||||
var items = [];
|
||||
if(privs.includes('setWIP')) items.push({label: kanbanLang.WIP, icon: '', url: createLink('kanban', 'setWIP', 'columnID=' + column.id), attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('editColumn')) items.push({label: kanbanLang.editColumn, icon: '', url: createLink('kanban', 'editColumn', 'columnID=' + column.id), attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('setWIP')) items.push({label: kanbanLang.WIP, icon: '', url: createLink('kanban', 'setWIP', 'columnID=' + column.id), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('editColumn')) items.push({label: kanbanLang.editColumn, icon: '', url: createLink('kanban', 'setColumn', 'columnID=' + column.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('createColumn'))
|
||||
{
|
||||
items.push({label: kanbanLang.createColumnOnLeft, icon: '', url: createLink('kanban', 'createColumn', 'columnID=' + column.id + '&position=left'), attrs: {'data-toggle': 'modal'}});
|
||||
items.push({label: kanbanLang.createColumnOnRight, icon: '', url: createLink('kanban', 'createColumn', 'columnID=' + column.id + '&position=right'), attrs: {'data-toggle': 'modal'}});
|
||||
items.push({label: kanbanLang.createColumnOnLeft, icon: '', url: createLink('kanban', 'createColumn', 'columnID=' + column.id + '&position=left'), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
items.push({label: kanbanLang.createColumnOnRight, icon: '', url: createLink('kanban', 'createColumn', 'columnID=' + column.id + '&position=right'), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
}
|
||||
if(privs.includes('copyColumn')) items.push({label: kanbanLang.copyColumn, icon: '', url: createLink('kanban', 'copyColumn', 'columnID=' + column.id), attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('splitColumn')) items.push({label: kanbanLang.splitColumn, icon: '', url: createLink('kanban', 'splitColumn', 'columnID=' + column.id), attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('copyColumn')) items.push({label: kanbanLang.copyColumn, icon: '', url: createLink('kanban', 'copyColumn', 'columnID=' + column.id), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('splitColumn')) items.push({label: kanbanLang.splitColumn, icon: '', url: createLink('kanban', 'splitColumn', 'columnID=' + column.id), className: 'iframe', attrs: {'data-toggle': 'modal'}});
|
||||
if(privs.includes('archiveColumn')) items.push({label: kanbanLang.archiveColumn, icon: '', url: createLink('kanban', 'archiveColumn', 'columnID=' + column.id), className: 'confirmer', attrs: {'data-confirmTitle': kanbancolumnLang.confirmArchive, 'data-confirmDetail': kanbancolumnLang.confirmArchiveDetail, 'data-confirmButton': lang.archive, 'data-confirming': lang.archiving}});
|
||||
if(privs.includes('deleteColumn')) items.push({label: kanbanLang.deleteColumn, icon: '', url: createLink('kanban', 'deleteColumn', 'columnID=' + column.id), className: 'confirmer', attrs: {'data-confirmTitle': kanbancolumnLang.confirmDelete, 'data-confirmDetail': kanbancolumnLang.confirmDeleteDetail}});
|
||||
|
||||
|
||||
@@ -100,6 +100,9 @@ $lang->kanban->laneGroup = 'Lane Group';
|
||||
$lang->kanban->cardsSort = 'Cards Sortting';
|
||||
$lang->kanban->moreAction = 'More Action';
|
||||
$lang->kanban->noGroup = 'None';
|
||||
$lang->kanban->limitExceeded = 'Limit Exceeded';
|
||||
$lang->kanban->fullScreen = 'Full Screen';
|
||||
$lang->kanban->setting = 'Setting';
|
||||
|
||||
$lang->kanban->error = new stdclass();
|
||||
$lang->kanban->error->mustBeInt = 'The WIPs must be positive integer.';
|
||||
@@ -177,9 +180,22 @@ $lang->kanbancolumn->name = $lang->kanban->columnName;
|
||||
$lang->kanbancolumn->limit = $lang->kanban->WIPCount;
|
||||
|
||||
$lang->kanbanlane = new stdclass();
|
||||
$lang->kanbanlane->name = $lang->kanban->laneName;
|
||||
$lang->kanbanlane->common = 'Lane';
|
||||
$lang->kanbanlane->default = 'Default Lane';
|
||||
$lang->kanbanlane->column = 'Lane Kanban column';
|
||||
$lang->kanbanlane->otherlane = 'Select the lane that shares the Kanban column';
|
||||
$lang->kanbanlane->color = 'Lane color';
|
||||
|
||||
$lang->kanbanlane->modeList['sameAsOther'] = 'Use the same Kanban column as other lanes';
|
||||
$lang->kanbanlane->modeList['independent'] = 'Independent Kanban column is adopted';
|
||||
|
||||
$lang->kanbanlane->name = $lang->kanban->laneName;
|
||||
$lang->kanbanlane->common = 'Lane';
|
||||
$lang->kanbanlane->default = 'Default Lane';
|
||||
|
||||
$lang->kanbanregion = new stdclass();
|
||||
$lang->kanbanregion->name = 'Kanban Region';
|
||||
$lang->kanbanregion->default = 'Default Region';
|
||||
|
||||
$lang->kanbancard = new stdclass();
|
||||
@@ -180,9 +180,15 @@ $lang->kanbancolumn->name = $lang->kanban->columnName;
|
||||
$lang->kanbancolumn->limit = $lang->kanban->WIPCount;
|
||||
|
||||
$lang->kanbanlane = new stdclass();
|
||||
$lang->kanbanlane->name = $lang->kanban->laneName;
|
||||
$lang->kanbanlane->common = '泳道';
|
||||
$lang->kanbanlane->default = '默认泳道';
|
||||
$lang->kanbanlane->name = $lang->kanban->laneName;
|
||||
$lang->kanbanlane->common = '泳道';
|
||||
$lang->kanbanlane->default = '默认泳道';
|
||||
$lang->kanbanlane->column = '泳道看板列';
|
||||
$lang->kanbanlane->otherlane = '选择共享看板列的泳道';
|
||||
$lang->kanbanlane->color = '泳道颜色';
|
||||
|
||||
$lang->kanbanlane->modeList['sameAsOther'] = '与其他泳道使用相同看板列';
|
||||
$lang->kanbanlane->modeList['independent'] = '采用独立的看板列';
|
||||
|
||||
$lang->kanbanregion = new stdclass();
|
||||
$lang->kanbanregion->name = '看板区域';
|
||||
|
||||
@@ -152,6 +152,7 @@ class kanbanModel extends model
|
||||
$lane->region = $regionID;
|
||||
$lane->type = 'common';
|
||||
$lane->lastEditedTime = helper::now();
|
||||
$lane->color = '#7ec5ff';
|
||||
|
||||
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
|
||||
$laneID = $this->dao->lastInsertId();
|
||||
@@ -180,6 +181,7 @@ class kanbanModel extends model
|
||||
$column->name = $columnName;
|
||||
$column->type = $index;
|
||||
$column->limit = -1;
|
||||
$column->color = '#333';
|
||||
|
||||
$this->dao->insert(TABLE_KANBANCOLUMN)->data($column)->exec();
|
||||
|
||||
@@ -688,6 +690,72 @@ class kanbanModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lane pairs by region id.
|
||||
*
|
||||
* @param array $regionID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLanePairsByRegion($regionID)
|
||||
{
|
||||
return $this->dao->select('id, name')->from(TABLE_KANBANLANE)
|
||||
->where('deleted')->eq('0')
|
||||
->andWhere('region')->eq($regionID)
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a lane.
|
||||
*
|
||||
* @param int $kanbanID
|
||||
* @param int $regionID
|
||||
* @param object $lane
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createLane($kanbanID, $regionID, $lane = null)
|
||||
{
|
||||
if(empty($lane))
|
||||
{
|
||||
$maxOrder = $this->dao->select('MAX(`order`) AS maxOrder')->from(TABLE_KANBANLANE)
|
||||
->where('region')->eq($regionID)
|
||||
->fetch('maxOrder');
|
||||
$lane = fixer::input('post')
|
||||
->add('region', $regionID)
|
||||
->add('order', $maxOrder + 1)
|
||||
->add('lastEditedTime', helper::today())
|
||||
->add('type', 'common')
|
||||
->setDefault('color', '#3DC6FD')
|
||||
->get();
|
||||
|
||||
$mode = zget($lane, 'mode', '');
|
||||
if($mode == 'sameAsOther')
|
||||
{
|
||||
$otherLane = zget($lane, 'otherLane', 0);
|
||||
if($otherLane) $lane->group = $this->dao->select('`group`')->from(TABLE_KANBANLANE)->where('id')->eq($otherLane)->fetch('group');
|
||||
}
|
||||
elseif($mode == 'independent')
|
||||
{
|
||||
$groupID = $this->createGroup($kanbanID, $regionID);
|
||||
$this->createDefaultColumns($kanban, $regionID, $groupID);
|
||||
|
||||
$lane->group = $groupID;
|
||||
}
|
||||
}
|
||||
|
||||
$this->dao->insert(TABLE_KANBANLANE)->data($lane, $skip = 'mode,otherLane')
|
||||
->batchCheck($this->config->kanban->require->createlane, 'notempty')
|
||||
->autoCheck()
|
||||
->checkIF(!empty($lane->name), 'name', 'unique', "`type`='common'")
|
||||
->exec();
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$laneID = $this->dao->lastInsertID();
|
||||
$this->loadModel('action')->create('kanbanLane', $laneID, 'Created');
|
||||
|
||||
return $laneID;
|
||||
}
|
||||
|
||||
* Create a kanban.
|
||||
*
|
||||
* @access public
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
<?php echo $lang->kanban->createLane;?>
|
||||
</h2>
|
||||
</div>
|
||||
<form class='load-indicator main-form' method='post' target='hiddenwin'>
|
||||
<table class='table table-form'>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="w-140px"><?php echo $lang->kanbanlane->name;?></th>
|
||||
<td>
|
||||
<div class='required required-wrapper'></div>
|
||||
<?php echo html::input('name', '', "class='form-control'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->column;?></th>
|
||||
<td><?php echo html::radio('mode', $lang->kanbanlane->modeList, 'sameAsOther');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->otherlane;?></th>
|
||||
<td><?php echo html::select('otherLane', $lanes, '', "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->kanbanlane->color;?></th>
|
||||
<td>
|
||||
<div id='color-picker'></div>
|
||||
<?php echo html::input('color', '#3DC6FD', "class='hidden'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td class='form-actions'>
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::backButton($lang->cancel);?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
Reference in New Issue
Block a user