This commit is contained in:
zhujinyong
2022-06-02 08:33:12 +08:00
30 changed files with 451 additions and 292 deletions
+36 -24
View File
@@ -324,12 +324,12 @@ class bug extends control
if($this->app->tab == 'execution')
{
if(isset($output['executionID'])) $this->loadModel('execution')->setMenu($output['executionID']);
$execution = $this->dao->findById((int)$output['executionID'])->from(TABLE_EXECUTION)->fetch();
$execution = $this->dao->findById($this->session->execution)->from(TABLE_EXECUTION)->fetch();
if($execution->type == 'kanban')
{
$this->loadModel('kanban');
$regionPairs = $this->kanban->getRegionPairs($execution->id, 0, 'execution');
$regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs);
$regionID = !empty($output['regionID']) ? $output['regionID'] : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'bug');
$laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs);
@@ -411,8 +411,10 @@ class bug extends control
$execution = $this->loadModel('execution')->getByID($executionID);
if($executionID == $output['executionID'] and $this->app->tab == 'execution' and $execution->type == 'kanban')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
}
else
@@ -707,8 +709,10 @@ class bug extends control
$execution = $this->loadModel('execution')->getByID($executionID);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
else
@@ -736,9 +740,9 @@ class bug extends control
{
$this->loadModel('kanban');
$regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution');
$regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs);
$regionID = !empty($output['regionID']) ? $output['regionID'] : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'bug');
$laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs);
$laneID = !empty($output['laneID']) ? $output['laneID'] : key($lanePairs);
$this->view->executionType = $execution->type;
$this->view->regionID = $regionID;
@@ -957,9 +961,9 @@ class bug extends control
if(isonlybody())
{
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution' and $kanbanGroup == 'default')
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', 0, $kanbanGroup);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
@@ -1271,9 +1275,9 @@ class bug extends control
{
$bug = $this->bug->getById($bugID);
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution' and $kanbanGroup == 'default')
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', 0, $kanbanGroup);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
@@ -1480,9 +1484,11 @@ class bug extends control
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1572,9 +1578,11 @@ class bug extends control
{
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1671,9 +1679,11 @@ class bug extends control
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1729,9 +1739,11 @@ class bug extends control
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
+5 -3
View File
@@ -544,13 +544,15 @@ class buildModel extends model
if($type == 'browse')
{
$executionID = $tab == 'execution' ? $extraParams['executionID'] : $build->execution;
$execution = $this->loadModel('execution')->getByID($executionID);
$testtaskApp = (!empty($execution->type) and $execution->type == 'kanban') ? 'data-app="qa"' : "data-app='{$tab}'";
if(common::hasPriv('build', 'linkstory') and common::canBeChanged('build', $build)) $menu .= $this->buildMenu('build', 'view', "{$params}&type=story&link=true", $build, $type, 'link', '', '', '', "data-app={$tab}", $this->lang->build->linkStory);
$menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id", $build, $type, 'bullhorn', '', '', '', "data-app='{$tab}'");
$menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id", $build, $type, 'bullhorn', '', '', '', $testtaskApp);
if($tab == 'execution') $menu .= $this->buildMenu('execution', 'bug', "execution={$extraParams['executionID']}&productID={$extraParams['productID']}&orderBy=status&build=$build->id", $build, $type, '', '', '', '', $this->lang->execution->viewBug);
if($tab == 'project') $menu .= $this->buildMenu('build', 'view', "{$params}&type=generatedBug", $build, $type, 'bug', '', '', '', "data-app='project'", $this->lang->project->bug);
if($tab == 'execution' and !empty($execution->type) and $execution->type != 'kanban') $menu .= $this->buildMenu('execution', 'bug', "execution={$extraParams['executionID']}&productID={$extraParams['productID']}&orderBy=status&build=$build->id", $build, $type, '', '', '', '', $this->lang->execution->viewBug);
if($tab == 'project' or empty($execution->type) or $execution->type == 'kanban') $menu .= $this->buildMenu('build', 'view', "{$params}&type=generatedBug", $build, $type, 'bug', '', '', '', "data-app='$tab'", $this->lang->project->bug);
$menu .= $this->buildMenu('build', 'edit', $params, $build, $type);
$menu .= $this->buildMenu('build', 'delete', $params, $build, $type, 'trash', 'hiddenwin');
+9 -3
View File
@@ -291,9 +291,15 @@ $lang->waterfall->menu->design['subMenu']->ads = array('link' => "{$lang->d
$lang->waterfall->menu->design['subMenu']->bysearch = array('link' => '<a href="javascript:;" class="querybox-toggle"><i class="icon-search icon"></i> ' . $lang->searchAB . '</a>');
/* Kanban project menu. */
$lang->kanban->menu = new stdclass();
$lang->kanban->menuOrder = array();
$lang->kanban->dividerMenu = '';
$lang->kanbanProject = new stdclass();
$lang->kanbanProject->menu = new stdclass();
$lang->kanbanProject->menu->index = array('link' => "{$lang->kanban->common}|project|index|project=%s");
$lang->kanbanProject->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s");
$lang->kanbanProject->menuOrder = array();
$lang->kanbanProject->menuOrder[5] = 'index';
$lang->kanbanProject->menuOrder[10] = 'build';
$lang->kanbanProject->dividerMenu = '';
/* Execution menu. */
$lang->execution->homeMenu = new stdclass();
+1
View File
@@ -1,5 +1,6 @@
<?php
$config->datatable->moduleAlias['product-browse'] = 'story';
$config->datatable->moduleAlias['execution-story'] = 'story';
$config->datatable->moduleAlias['execution-task'] = 'task';
$config->datatable->moduleAlias['testtask-cases'] = 'testcase';
$config->datatable->moduleAlias['program-project'] = 'project';
+16 -8
View File
@@ -855,6 +855,7 @@ class execution extends control
$this->view->branchGroups = $branchGroups;
$this->view->canBeChanged = common::canModify('execution', $execution); // Determines whether an object is editable.
$this->view->showBranch = $showBranch;
$this->view->storyStages = $this->product->batchGetStoryStage($stories);
$this->display();
}
@@ -2115,8 +2116,10 @@ class execution extends control
$this->loadModel('story');
if(empty($groupBy)) $groupBy = 'default';
/* Set Session. */
$this->session->set('execLaneType', $browseType);
$this->session->set('execGroupBy', $groupBy);
$this->session->set('storyList', $this->app->getURI(true), 'execution');
$this->lang->execution->menu = new stdclass();
@@ -2197,16 +2200,16 @@ class execution extends control
* @access public
* @return void
*/
public function taskKanban($executionID, $browseType = '', $orderBy = 'order_asc', $groupBy = '')
public function taskKanban($executionID, $browseType = 'all', $orderBy = 'order_asc', $groupBy = '')
{
if(empty($browseType)) $browseType = $this->session->kanbanType ? $this->session->kanbanType : 'all';
if(empty($groupBy)) $groupBy = 'default';
/* Save to session. */
$uri = $this->app->getURI(true);
$this->app->session->set('taskList', $uri, 'execution');
$this->app->session->set('bugList', $uri, 'qa');
$this->app->session->set('kanbanType', $browseType, 'execution');
$this->app->session->set('execLaneType', $browseType);
$this->app->session->set('execGroupBy', $groupBy);
/* Load language. */
$this->app->loadLang('task');
@@ -2853,8 +2856,10 @@ class execution extends control
{
if($this->app->tab == 'execution' and $object->type == 'kanban')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($objectID, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($objectID, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent', '', "parent.updateKanban($kanbanData)"));
}
@@ -3656,10 +3661,11 @@ class execution extends control
* @param int $productID
* @param string $fromMethod
* @param string $extra
* @param string $param
* @access public
* @return void
*/
public function importPlanStories($executionID, $planID, $productID = 0, $fromMethod = 'story', $extra = '')
public function importPlanStories($executionID, $planID, $productID = 0, $fromMethod = 'story', $extra = '', $param = '')
{
$planStories = $planProducts = array();
$planStory = $this->loadModel('story')->getPlanStories($planID);
@@ -3687,7 +3693,8 @@ class execution extends control
}
$moduleName = 'execution';
$param = "executionID=$executionID";
if(empty($param)) $param = "executionID=$executionID";
if(!empty($param)) $param = str_replace(array(',', ' '), array('&', ''), $param);
if($execution->type == 'project')
{
$moduleName = 'projectstory';
@@ -3700,7 +3707,8 @@ class execution extends control
$lang->executionCommon = $lang->execution->kanban;
include $this->app->getModulePath('', 'execution') . 'lang/' . $this->app->getClientLang() . '.php';
}
if($count != 0) echo js::alert(sprintf($this->lang->execution->haveDraft, $count)) . js::locate($this->createLink($moduleName, in_array($execution->type, array('sprint','project')) ? 'story' : 'kanban', $param));
if($count != 0) echo js::alert(sprintf($this->lang->execution->haveDraft, $count)) . js::locate($this->createLink($moduleName, $fromMethod, $param));
return print(js::locate(helper::createLink($moduleName, $fromMethod, $param)));
}
+34 -22
View File
@@ -180,7 +180,7 @@ function changeKanbanScaleSize(newScaleSize)
}
else
{
var kanban = $('#kanban').data('zui.kanban');
var kanban = $('#kanban' + executionID).data('zui.kanban');
if(!kanban) return;
kanban.setOptions({cardsPerRow: newScaleSize, cardHeight: getCardHeight()});
}
@@ -272,7 +272,7 @@ function createColumnCreateMenu(options)
var col = $col.data('col');
var items = [];
var laneID = col.$kanbanData.lanes[0].id ? col.$kanbanData.lanes[0].id : 0;
var regionID = col.$kanbanData.region;
var regionID = col.$kanbanData.region == undefined ? 0 : col.$kanbanData.region;
if(col.type == 'backlog')
{
@@ -370,19 +370,22 @@ function findDropColumns($element, $root)
if(!kanbanRules) return $root.find('.kanban-lane-col:not([data-type="' + col.type + '"])');
var colRules = kanbanRules[col.type];
var groupID = $col.closest('.kanban-board').data().id;
var colRules = kanbanRules[col.type];
var groupID = $col.closest('.kanban-board').data().id;
var oldLaneID = $col.closest('.kanban-lane').data().id;
return $root.find('.kanban-lane-col').filter(function()
{
if(!colRules) return false;
if(colRules === true) return true;
if($.cookie('isFullScreen') == 1) return false;
var $newCol = $(this);
var newCol = $newCol.data();
var newGroupID = $newCol.closest('.kanban-board').data().id;
var $newCol = $(this);
var newCol = $newCol.data();
var newGroupID = $newCol.closest('.kanban-board').data().id;
var newLaneID = $newCol.closest('.kanban-lane').data().id;
var canDropHere = colRules.indexOf(newCol.type) > -1 && newGroupID === groupID;
if(groupBy && groupBy != 'default' && canDropHere) canDropHere = oldLaneID === newLaneID;
if(canDropHere) $newCol.addClass('can-drop-here');
return canDropHere;
});
@@ -429,7 +432,8 @@ function renderUserAvatar(user, objectType, objectID, size, objectStatus)
if(objectType == 'story' && !priv.canAssignStory) return $noPrivAvatar;
if(objectType == 'bug' && !priv.canAssignBug) return $noPrivAvatar;
return objectStatus == 'closed' ? '' : $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + user.realname + '" href="' + link + '"/>').avatar({user: user}).attr('data-toggle', 'modal').attr('data-width', '80%');
var realname = user.realname ? user.realname : user.account;
return objectStatus == 'closed' ? '' : $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + realname + '" href="' + link + '"/>').avatar({user: user}).attr('data-toggle', 'modal').attr('data-width', '80%');
}
/**
@@ -690,8 +694,6 @@ function renderCount($count, count, column)
*/
function renderHeaderCol($column, column, $header, kanbanData)
{
if(groupBy != 'default') return;
/* Render group header. */
var privs = kanbanData.actions;
var columnPrivs = kanbanData.columns[0].actions;
@@ -703,7 +705,7 @@ function renderHeaderCol($column, column, $header, kanbanData)
$actions = $column.children('.actions');
}
if(privs.includes('sortGroup'))
if(groupBy == 'default' && privs.includes('sortGroup'))
{
var groups = regions[column.region].groups;
if($header.closest('.kanban').data('zui.kanban'))
@@ -777,6 +779,8 @@ function renderLaneName($lane, lane, $kanban, columns, kanban)
*/
function updateRegion(regionID, regionData = [])
{
if(groupBy != 'default') regionID = executionID;
if(!regionID) return false;
var $region = $('#kanban'+ regionID).kanban();
@@ -784,7 +788,8 @@ function updateRegion(regionID, regionData = [])
if(!$region.length) return false;
if(!regionData) regionData = regions[regionID];
$region.data('zui.kanban').render(regionData.groups);
var data = groupBy == 'default' ? regionData.groups : regionData;
$region.data('zui.kanban').render(data);
resetRegionHeight('open');
return true;
}
@@ -832,8 +837,6 @@ var kanbanActionHandlers =
*/
function handleKanbanAction(action, $element, event, kanban)
{
if(groupBy && groupBy != 'default') return false;
$('.kanban').attr('data-action-enabled', action);
var handler = kanbanActionHandlers[action];
if(handler) handler($element, event, kanban);
@@ -860,6 +863,8 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
var showIframe = false;
var moveCard = false;
regionID = regionID ? regionID : 0;
/* Task lane. */
if(cardType == 'task')
{
@@ -989,7 +994,8 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
url: link,
success: function(data)
{
updateRegion(regionID, data[regionID]);
data = groupBy == 'default' ? data[regionID] : data[groupBy];
updateRegion(regionID, data);
},
error: function(xhr, status, error)
{
@@ -1018,6 +1024,8 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
function deleteCard(objectType, objectID, regionID)
{
$.zui.ContextMenu.hide();
regionID = regionID ? regionID : 0;
setTimeout(function()
{
var objectLang = objectType + 'Lang';
@@ -1034,7 +1042,8 @@ function deleteCard(objectType, objectID, regionID)
url: url,
success: function(data)
{
updateRegion(regionID, data[regionID]);
data = groupBy == 'default' ? data[regionID] : data[groupBy];
updateRegion(regionID, data);
}
});
}, 200)
@@ -1053,7 +1062,7 @@ function updateKanban(kanbanData, regionID = 0)
setTimeout(function()
{
$.zui.closeModal();
if(regionID)
if(regionID && groupBy == 'default')
{
updateRegion(regionID, kanbanData[regionID]);
}
@@ -1062,7 +1071,8 @@ function updateKanban(kanbanData, regionID = 0)
$('#kanban').children('.region').children("div[id^='kanban']").each(function()
{
var regionID = $(this).attr('data-id');
updateRegion(regionID, kanbanData[regionID]);
var data = groupBy == 'default' ? kanbanData[regionID] : kanbanData[groupBy]
updateRegion(regionID, data);
});
}
}, 200);
@@ -1091,7 +1101,8 @@ function shiftCard(objectID, fromColID, toColID, fromLaneID, toLaneID, regionID)
url: link,
success: function(data)
{
updateRegion(regionID, data[regionID]);
data = groupBy == 'default' ? data[regionID] : data[groupBy];
updateRegion(regionID, data);
},
error: function(xhr, status, error)
{
@@ -1230,7 +1241,7 @@ function initKanban($kanban)
onRenderLaneName: renderLaneName,
onRenderHeaderCol: renderHeaderCol,
onRenderCount: renderCount,
droppable: groupBy == 'default' ? {target: findDropColumns, finish:handleFinishDrop} : false,
droppable: {target: findDropColumns, finish:handleFinishDrop},
virtualize: true,
virtualCardList: true
});
@@ -1317,8 +1328,9 @@ $(function()
var planID = $('#plan').val();
if(planID)
{
var vars = $('.linkStoryByPlanButton').data('lane') != null ? '&extra=laneID='+ $('.linkStoryByPlanButton').data('lane') + ',columnID=' + $('.linkStoryByPlanButton').data('col') : '';
location.href = createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=kanban' + vars);
var vars = $('.linkStoryByPlanButton').data('lane') != null ? '&extra=laneID='+ $('.linkStoryByPlanButton').data('lane') + ',columnID=' + $('.linkStoryByPlanButton').data('col') : '';
var param = "&param=executionID=" + executionID + ",browseType=" + browseType + ",orderBy=id_asc,groupBy=" + groupBy;
location.href = createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=kanban' + vars + param);
$.closeModal();
}
});
+2
View File
@@ -1,5 +1,7 @@
$(function()
{
if($('#storyList thead th.c-title').width() < 150) $('#storyList thead th.c-title').width(150);
$('#storyList').on('sort.sortable', function(e, data)
{
var list = '';
+4 -5
View File
@@ -45,7 +45,8 @@ function renderUserAvatar(user, objectType, objectID, size, objectStatus)
if(objectType == 'story' && !priv.canAssignStory) return $noPrivAvatar;
if(objectType == 'bug' && !priv.canAssignBug) return $noPrivAvatar;
return objectStatus == 'closed' ? '' : $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + user.realname + '" href="' + link + '"/>').avatar({user: user});
var realname = user.realname ? user.realname : user.account;
return objectStatus == 'closed' ? '' : $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + realname + '" href="' + link + '"/>').avatar({user: user});
}
/**
@@ -783,7 +784,6 @@ var kanbanActionHandlers =
*/
function handleKanbanAction(action, $element, event, kanban)
{
if(groupBy && groupBy != 'default') return false;
$('.kanban').attr('data-action-enabled', action);
var handler = kanbanActionHandlers[action];
if(handler) handler($element, event, kanban);
@@ -1074,8 +1074,6 @@ $(function()
onRenderCount: renderColumnCount
};
if(groupBy != 'default') commonOptions.droppable = false;
/* Create kanban */
if(groupBy == 'default')
{
@@ -1141,7 +1139,8 @@ $(function()
var planID = $('#plan').val();
if(planID)
{
location.href = createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=kanban');
var param = "&param=executionID=" + executionID + ",browseType=" + browseType + ",orderBy=id_asc,groupBy=" + groupBy;
location.href = createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=taskKanban&extra=' + param);
}
});
+3
View File
@@ -67,6 +67,9 @@ class executionModel extends model
if($execution and $execution->type == 'kanban')
{
$this->lang->execution->menu = new stdclass();
$this->lang->execution->menu->kanban = array('link' => "{$this->lang->kanban->common}|execution|kanban|executionID=%s");
$this->lang->execution->menu->build = array('link' => "{$this->lang->build->common}|execution|build|executionID=%s");
$this->lang->execution->dividerMenu = '';
$this->lang->execution->accessDenied = str_replace($this->lang->executionCommon, $this->lang->execution->kanban, $this->lang->execution->accessDenied);
}
+10 -5
View File
@@ -138,15 +138,16 @@ js::set('hasTaskButton', $hasTaskButton);
<div class='btn-toolbar pull-right'>
<?php
echo html::a('javascript:fullScreen()', "<i class='icon-fullscreen muted'></i> " . $lang->kanban->fullScreen, '', "class='btn btn-link'");
$actions = '';
$printSettingBtn = (common::hasPriv('kanban', 'createRegion') or (common::hasPriv('kanban', 'setLaneHeight')) or (common::hasPriv('kanban', 'setColumnWidth')) or common::hasPriv('execution', 'edit') or common::hasPriv('execution', 'close') or common::hasPriv('execution', 'delete') or !empty($executionActions));
$actions = '';
$printCreateRegion = (common::hasPriv('kanban', 'createRegion') and $groupBy == 'default');
$printSettingBtn = ($printCreateRegion or (common::hasPriv('kanban', 'setLaneHeight')) or (common::hasPriv('kanban', 'setColumnWidth')) or common::hasPriv('execution', 'edit') or common::hasPriv('execution', 'close') or common::hasPriv('execution', 'delete') or !empty($executionActions));
if($printSettingBtn)
{
$actions .= html::a('javascript:;', "<i class='icon icon-cog-outline'></i>" . $lang->kanban->setting, '', "data-toggle='dropdown' class='btn btn-link'");
$actions .= "<ul id='kanbanActionMenu' class='dropdown-menu pull-right'>";
$width = $this->app->getClientLang() == 'en' ? '750' : '650';
if(common::hasPriv('kanban', 'createRegion')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'createRegion', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-plus"></i>' . $lang->kanban->createRegion, '', "class='iframe btn btn-link text-left'") . '</li>';
if($printCreateRegion) $actions .= '<li>' . html::a(helper::createLink('kanban', 'createRegion', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-plus"></i>' . $lang->kanban->createRegion, '', "class='iframe btn btn-link text-left'") . '</li>';
if(common::hasPriv('kanban', 'setLaneHeight')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'setLaneHeight', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-size-height"></i>' . $lang->kanban->laneHeight, '', "class='iframe btn btn-link text-left' data-width=$width") . '</li>';
if(common::hasPriv('kanban', 'setColumnWidth')) $actions .= '<li>' . html::a(helper::createLink('kanban', 'setColumnWidth', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-size-width"></i>' . $lang->kanban->columnWidth, '', "class='iframe btn btn-link text-left' data-width='400'") . '</li>';
$kanbanActions = '';
@@ -232,8 +233,12 @@ js::set('hasTaskButton', $hasTaskButton);
</div>
<?php else:?>
<div class='panel' id='kanbanContainer'>
<div class='panel-body region'>
<div id='kanban' class='kanban'></div>
<div class='panel-body'>
<div id='kanban'>
<div class='region'>
<div id='kanban<?php echo $execution->id;?>' data-id='<?php echo $execution->id;?>' class='kanban'></div>
</div>
</div>
</div>
</div>
<?php endif;?>
+43 -138
View File
@@ -161,6 +161,9 @@
</div>
<div class="main-col">
<div id='queryBox' data-module='executionStory' class='cell <?php if($type =='bysearch') echo 'show';?>'></div>
<div class="table-header fixed-right">
<nav class="btn-toolbar pull-right setting"></nav>
</div>
<?php if(empty($stories)):?>
<div class="table-empty-tip">
<p>
@@ -172,48 +175,41 @@
</div>
<?php else:?>
<form class='main-table table-story skip-iframe-modal' method='post' id='executionStoryForm'>
<div class="table-header fixed-right">
<nav class="btn-toolbar pull-right"></nav>
</div>
<table class='table tablesorter has-sort-head' id='storyList'>
<?php
$datatableId = $this->moduleName . ucfirst($this->methodName);
$useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable');
$vars = "executionID={$execution->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
if($useDatatable) include '../../common/view/datatable.html.php';
$setting = $this->datatable->getSetting('execution');
$widths = $this->datatable->setFixedFieldWidth($setting);
$columns = 0;
$checkObject = new stdclass();
$checkObject->execution = $execution->id;
$totalEstimate = 0;
$canBatchEdit = common::hasPriv('story', 'batchEdit');
$canBatchClose = common::hasPriv('story', 'batchClose');
$canBatchChangeStage = common::hasPriv('story', 'batchChangeStage');
$canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory');
$canBatchToTask = common::hasPriv('story', 'batchToTask', $checkObject);
$canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchClose or $canBatchChangeStage or $canBatchUnlink or $canBatchToTask));
?>
<?php if(!$useDatatable) echo '<div class="table-responsive">';?>
<table class='table tablesorter has-sort-head<?php if($useDatatable) echo ' datatable';?>' id='storyList' data-fixed-left-width='<?php echo $widths['leftWidth']?>' data-fixed-right-width='<?php echo $widths['rightWidth']?>'>
<thead>
<tr>
<?php
$checkObject = new stdclass();
$checkObject->execution = $execution->id;
$totalEstimate = 0;
$canBatchEdit = common::hasPriv('story', 'batchEdit');
$canBatchClose = common::hasPriv('story', 'batchClose');
$canBatchChangeStage = common::hasPriv('story', 'batchChangeStage');
$canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory');
$canBatchToTask = common::hasPriv('story', 'batchToTask', $checkObject);
$canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchClose or $canBatchChangeStage or $canBatchUnlink or $canBatchToTask));
foreach($setting as $key => $value)
{
if($value->show)
{
$this->datatable->printHead($value, $orderBy, $vars, $canBatchAction);
$columns ++;
}
}
?>
<?php $vars = "executionID={$execution->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
<th class='c-id {sorter:false}'>
<?php if($canBatchAction):?>
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<?php if($canOrder):?>
<th class='c-sort {sorter:false}'><?php common::printOrderLink('order', $orderBy, $vars, $lang->execution->orderAB);?></th>
<?php endif;?>
<th class='c-pri {sorter:false}' title=<?php echo $lang->execution->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-name {sorter:false}'><?php common::printOrderLink('title', $orderBy, $vars, $lang->execution->storyTitle);?></th>
<th class='c-category {sorter:false}'><?php common::printOrderLink('category', $orderBy, $vars, $lang->story->category);?></th>
<th class='c-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-assignedTo {sorter:false} text-center'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='c-estimate {sorter:false} text-right'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage {sorter:false}'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th title='<?php echo $lang->story->taskCount?>' class='c-count'><?php echo $lang->story->taskCountAB;?></th>
<th title='<?php echo $lang->story->bugCount?>' class='c-count'><?php echo $lang->story->bugCountAB;?></th>
<th title='<?php echo $lang->story->caseCount?>' class='c-count'><?php echo $lang->story->caseCountAB;?></th>
<th class='c-actions-7 text-center {sorter:false}'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody id='storyTableList' class='sortable'>
@@ -223,110 +219,16 @@
$totalEstimate += $story->estimate;
?>
<tr id="story<?php echo $story->id;?>" data-id='<?php echo $story->id;?>' data-order='<?php echo $story->order ?>' data-estimate='<?php echo $story->estimate?>' data-cases='<?php echo zget($storyCases, $story->id, 0)?>'>
<td class='cell-id'>
<?php if($canBatchAction):?>
<?php echo html::checkbox('storyIdList', array($story->id => '')) . html::a(helper::createLink('story', 'view', "storyID=$story->id&version=$story->version&from=execution&param=$execution->id"), sprintf('%03d', $story->id), null, "data-app='execution'");?>
<?php else:?>
<?php printf('%03d', $story->id);?>
<?php endif;?>
</td>
<?php if($canOrder):?>
<td class='sort-handler c-sort'><i class='icon-move'></i></td>
<?php endif;?>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $story->pri?>' title='<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td class='c-name' title="<?php echo $story->title?>">
<?php if($showBranch) $showBranch = isset($this->config->execution->story->showBranch) ? $this->config->execution->story->showBranch : 1;?>
<?php if(isset($branchGroups[$story->product][$story->branch]) and $showBranch) echo "<span class='label label-outline label-badge' title={$branchGroups[$story->product][$story->branch]}>" . $branchGroups[$story->product][$story->branch] . '</span>';?>
<?php if(!empty($story->module) and isset($modulePairs[$story->module])) echo "<span class='label label-gray label-badge'>{$modulePairs[$story->module]}</span> ";?>
<?php if($story->parent > 0) echo "<span class='label'>{$lang->story->childrenAB}</span>";?>
<?php echo html::a($storyLink,$story->title, null, "style='color: $story->color' data-app='execution'");?>
</td>
<td class='c-category' title='<?php echo zget($lang->story->categoryList, $story->category);?>'><?php echo zget($lang->story->categoryList, $story->category);?></td>
<td class='c-user' title='<?php echo zget($users, $story->openedBy);?>'><?php echo zget($users, $story->openedBy);?></td>
<td class='c-assignedTo <?php if(zget($users, $story->assignedTo) == 'Closed') echo 'closed-story'?> text-center' title='<?php echo zget($users, $story->assignedTo);?>'><?php $this->loadModel('story')->printAssignedHtml($story,$users);?></td>
<td class='c-estimate text-right' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
<?php $status = $this->processStatus('story', $story);?>
<td class='c-status' title='<?php echo $status;?>'>
<span class='status-story status-<?php echo $story->status;?>'><?php echo $status;?></span>
</td>
<td class='c-stage'><?php echo $lang->story->stageList[$story->stage];?></td>
<td class='linkbox c-count'>
<?php
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&executionID=$execution->id");
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
?>
<td class='c-count'>
<?php
$bugsLink = $this->createLink('story', 'bugs', "storyID=$story->id&executionID=$execution->id");
$storyBugs[$story->id] > 0 ? print(html::a($bugsLink, $storyBugs[$story->id], '', 'class="iframe"')) : print(0);
?>
</td>
<td class='c-count'>
<?php
$casesLink = $this->createLink('story', 'cases', "storyID=$story->id&executionID=$execution->id");
$storyCases[$story->id] > 0 ? print(html::a($casesLink, $storyCases[$story->id], '', 'class="iframe"')) : print(0);
?>
</td>
<td class='c-actions'>
<?php
$hasDBPriv = common::hasDBPriv($execution, 'execution');
if($canBeChanged)
{
$param = "executionID={$execution->id}&story={$story->id}&moduleID={$story->module}";
$story->reviewer = isset($story->reviewer) ? $story->reviewer : array();
$story->notReview = isset($story->notReview) ? $story->notReview : array();
if(common::hasPriv('story', 'review'))
{
$reviewDisabled = in_array($app->user->account, $story->notReview) and ($story->status == 'draft' or $story->status == 'changed') ? '' : 'disabled';
$story->from = 'execution';
common::printIcon('story', 'review', "story={$story->id}&from=story", $story, 'list', 'search', '', $reviewDisabled, false, "data-group=execution");
}
if(common::hasPriv('story', 'recall'))
{
$recallDisabled = empty($story->reviewedBy) and strpos('draft,changed', $story->status) !== false and !empty($story->reviewer) ? '' : 'disabled';
common::printIcon('story', 'recall', "story={$story->id}", $story, 'list', 'undo', 'hiddenwin', $recallDisabled, '', '', $lang->story->recall);
}
$lang->task->create = $lang->execution->wbs;
$toTaskDisabled = strpos('draft,closed', $story->status) !== false ? 'disabled' : '';
if(commonModel::isTutorialMode())
{
$wizardParams = helper::safe64Encode($param);
echo html::a($this->createLink('tutorial', 'wizard', "module=task&method=create&params=$wizardParams"), "<i class='icon-plus'></i>",'', "class='btn btn-task-create' title='{$lang->execution->wbs}' data-app='execution'");
}
else
{
if($hasDBPriv) common::printIcon('task', 'create', $param, '', 'list', 'plus', '', 'btn-task-create ' . $toTaskDisabled);
}
$lang->task->batchCreate = $lang->execution->batchWBS;
if($hasDBPriv) common::printIcon('task', 'batchCreate', "executionID={$execution->id}&story={$story->id}", '', 'list', 'pluses', '', $toTaskDisabled);
$lang->testcase->batchCreate = $lang->testcase->create;
if($productID and $hasDBPriv and common::hasPriv('testcase', 'create'))
{
echo html::a($this->createLink('testcase', 'create', "productID=$story->product&branch=$story->branch&moduleID=$story->module&form=&param=0&storyID=$story->id"), '<i class="icon-testcase-create icon-sitemap"></i>', '', "class='btn' title='{$lang->testcase->create}' data-app='qa'");
}
if($canBeChanged and common::hasPriv('execution', 'storyEstimate', $execution))
{
common::printIcon('execution', 'storyEstimate', "executionID=$execution->id&storyID=$story->id", '', 'list', 'estimate', '', 'iframe', true, "data-width='600px'");
}
if($canBeChanged and common::hasPriv('execution', 'unlinkStory', $execution))
{
common::printIcon('execution', 'unlinkStory', "executionID=$execution->id&storyID=$story->id&confirm=no", '', 'list', 'unlink', 'hiddenwin');
}
}
?>
</td>
<?php foreach($setting as $key => $value)
{
$this->story->printCell($value, $story, $users, '', $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', '', $execution, $showBranch);
}
?>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php if(!$useDatatable) echo '</div>';?>
<div class='table-footer'>
<?php if($canBatchAction):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
@@ -491,6 +393,9 @@ function handleLinkButtonClick()
var xxcUrl = "xxc:openInApp/zentao-integrated/" + encodeURIComponent(window.location.href.replace(/.display=card/, '').replace(/\.xhtml/, '.html'));
window.open(xxcUrl);
}
<?php if(!empty($useDatatable)):?>
$(function(){$('#executionStoryForm').table();})
<?php endif;?>
</script>
<?php if(commonModel::isTutorialMode()): ?>
<style>
+1 -1
View File
@@ -87,7 +87,7 @@ $lang->install->sessionFail = 'Bearbeiten Sie die PHP ini Datei um den session.
$lang->install->mkdirWin = '<p>%s Verzeichnis muss erstellt werden.<br /> Befehl <code>mkdir %s</code> zur Erstellung.</p>';
$lang->install->chmodWin = ' "%s" Berechtigung muss geändert werden.';
$lang->install->mkdirLinux = '<p>%s Verzeichnis muss erstellt werden.<br /> Befehl <code>mkdir -p %s</code> zur Erstellung.</p>';
$lang->install->chmodLinux = ' "%s" Berechtigung muss geändert werden.<br /> Befehl <code>chmod o=rwx -R %s</code> für die Anpassung.';
$lang->install->chmodLinux = ' "%s" Berechtigung muss geändert werden.<br /> Befehl <code>chmod 777 -R %s</code> für die Anpassung.';
$lang->install->timezone = 'Set Timezone';
$lang->install->defaultLang = 'Standard Sprache';
+1 -1
View File
@@ -116,7 +116,7 @@ $lang->install->sessionFail = 'Edit the php.ini file to set session.save_path.'
$lang->install->mkdirWin = '<p>%s directory has to be created.<br /> Run <code>mkdir %s</code> to create it.</p>';
$lang->install->chmodWin = ' "%s" privilege has to be changed.';
$lang->install->mkdirLinux = '<p>%s directory has to be created.<br /> Run <code>mkdir -p %s</code> to create it.</p>';
$lang->install->chmodLinux = ' "%s" permison has to be changed.<br /> Run <code>chmod o=rwx -R %s</code> to change it.';
$lang->install->chmodLinux = ' "%s" permison has to be changed.<br /> Run <code>chmod 777 -R %s</code> to change it.';
$lang->install->timezone = 'Set Timezone';
$lang->install->defaultLang = 'Default Language';
+1 -1
View File
@@ -87,7 +87,7 @@ $lang->install->sessionFail = 'Editez le fichier php.ini pour définier session
$lang->install->mkdirWin = '<p>Le répertoire %s doit être créé.<br /> Exécutez <code>mkdir %s</code> pour le créer.</p>';
$lang->install->chmodWin = ' "%s" privilege has to be changed.';
$lang->install->mkdirLinux = '<p>Le répertoire %s doit être créé.<br /> Exécutez <code>mkdir -p %s</code> pour le créer.</p>';
$lang->install->chmodLinux = 'Les permission de "%s" doivent être modifiées.<br /> Exécutez <code>chmod o=rwx -R %s</code> pour les changer.';
$lang->install->chmodLinux = 'Les permission de "%s" doivent être modifiées.<br /> Exécutez <code>chmod 777 -R %s</code> pour les changer.';
$lang->install->timezone = 'Set Timezone';
$lang->install->defaultLang = 'Langue par défaut';
+1 -1
View File
@@ -87,7 +87,7 @@ $lang->install->sessionFail = 'Sửa the php.ini file to set session.save_path.
$lang->install->mkdirWin = '<p>%s directory has to be created.<br /> Run <code>mkdir %s</code> to create it.</p>';
$lang->install->chmodWin = ' "%s" privilege has to be changed.';
$lang->install->mkdirLinux = '<p>%s directory has to be created.<br /> Run <code>mkdir -p %s</code> to create it.</p>';
$lang->install->chmodLinux = ' "%s" permison has to be changed.<br /> Run <code>chmod o=rwx -R %s</code> to change it.';
$lang->install->chmodLinux = ' "%s" permison has to be changed.<br /> Run <code>chmod 777 -R %s</code> to change it.';
$lang->install->timezone = 'Thiết lập Timezone';
$lang->install->defaultLang = 'Ngôn ngữ mặc định';
+1 -1
View File
@@ -116,7 +116,7 @@ $lang->install->sessionFail = '修改PHP配置文件,设置session.save_path
$lang->install->mkdirWin = '<p>需要创建目录%s。命令为:<br /> mkdir %s</p>';
$lang->install->chmodWin = '需要修改目录 "%s" 的权限。';
$lang->install->mkdirLinux = '<p>需要创建目录%s。<br /> 命令为:<br /> mkdir -p %s</p>';
$lang->install->chmodLinux = '需要修改目录 "%s" 的权限。<br />命令为:<br />chmod o=rwx -R %s';
$lang->install->chmodLinux = '需要修改目录 "%s" 的权限。<br />命令为:<br />chmod 777 -R %s';
$lang->install->timezone = '时区设置';
$lang->install->defaultLang = '默认语言';
+1 -1
View File
@@ -116,7 +116,7 @@ $lang->install->sessionFail = '修改PHP配置檔案,設置session.save_path
$lang->install->mkdirWin = '<p>需要創建目錄%s。命令為:<br /> mkdir %s</p>';
$lang->install->chmodWin = '需要修改目錄 "%s" 的權限。';
$lang->install->mkdirLinux = '<p>需要創建目錄%s。<br /> 命令為:<br /> mkdir -p %s</p>';
$lang->install->chmodLinux = '需要修改目錄 "%s" 的權限。<br />命令為:<br />chmod o=rwx -R %s';
$lang->install->chmodLinux = '需要修改目錄 "%s" 的權限。<br />命令為:<br />chmod 777 -R %s';
$lang->install->timezone = '時區設置';
$lang->install->defaultLang = '預設語言';
+21 -10
View File
@@ -1479,9 +1479,10 @@ class kanban extends control
$this->loadModel($objectType)->delete(constant($table), $objectID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$kanbanID = $this->kanban->getKanbanIDByregion($regionID);
$kanbanID = $regionID ? $this->kanban->getKanbanIDByregion($regionID) : $this->session->execution;
$browseType = $this->config->vision == 'lite' ? 'task' : $this->session->execLaneType;
$kanbanGroup = $this->kanban->getRDKanban($kanbanID, $browseType);
$groupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanGroup = $this->kanban->getRDKanban($kanbanID, $browseType, 'id_desc', 0, $groupBy);
return print(json_encode($kanbanGroup));
}
@@ -1508,9 +1509,11 @@ class kanban extends control
if($from == 'RDKanban')
{
if(dao::isError()) return $this->sendError(dao::getError());
$regionID = $column->region;
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = $column->region;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1589,9 +1592,11 @@ class kanban extends control
if($from == 'RDKanban')
{
if(dao::isError()) return $this->sendError(dao::getError());
$regionID = $column->region;
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$regionID = $execGroupBy == 'default' ? $column->region : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1711,12 +1716,18 @@ class kanban extends control
*/
public function ajaxMoveCard($cardID = 0, $fromColID = 0, $toColID = 0, $fromLaneID = 0, $toLaneID = 0, $executionID = 0, $browseType = 'all', $groupBy = '', $regionID = 0, $orderBy = '')
{
$fromCell = $this->dao->select('id, cards')->from(TABLE_KANBANCELL)
$fromCell = $this->dao->select('id, cards, lane')->from(TABLE_KANBANCELL)
->where('kanban')->eq($executionID)
->andWhere('lane')->eq($fromLaneID)
->andWhere('`column`')->eq($fromColID)
->beginIF(!$groupBy or $groupBy == 'default')->andWhere('lane')->eq($fromLaneID)->fi()
->beginIF($groupBy and $groupBy != 'default')
->andWhere('type')->eq($browseType)
->andWhere('cards')->like("%,$cardID,%")
->fi()
->fetch();
if($groupBy and $groupBy != 'default') $fromLaneID = $toLaneID = $fromCell->lane;
$toCell = $this->dao->select('id, cards')->from(TABLE_KANBANCELL)
->where('kanban')->eq($executionID)
->andWhere('lane')->eq($toLaneID)
+45 -2
View File
@@ -1451,16 +1451,33 @@ class kanbanModel extends model
if($browseType == 'bug') $cardList = $this->loadModel('bug')->getExecutionBugs($executionID);
if($browseType == 'task') $cardList = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
/* Get objects cards menus. */
if($browseType == 'story') $storyCardMenu = $this->getKanbanCardMenu($executionID, $cardList, 'story');
if($browseType == 'bug') $bugCardMenu = $this->getKanbanCardMenu($executionID, $cardList, 'bug');
if($browseType == 'task') $taskCardMenu = $this->getKanbanCardMenu($executionID, $cardList, 'task');
$lanes = $this->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
if(empty($lanes)) return array();
$columns = $this->dao->select('t1.*, t2.`type` as columnType, t2.limit, t2.name as columnName, t2.color')->from(TABLE_KANBANCELL)->alias('t1')
$execution = $this->loadModel('execution')->getByID($executionID);
$columns = $this->dao->select('t1.*, GROUP_CONCAT(t1.cards) as cards, t2.`type` as columnType, t2.limit, t2.name as columnName, t2.color')->from(TABLE_KANBANCELL)->alias('t1')
->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.`column` = t2.id')
->leftJoin(TABLE_KANBANLANE)->alias('t3')->on('t1.lane = t3.id')
->leftJoin(TABLE_KANBANREGION)->alias('t4')->on('t1.kanban = t4.kanban')
->where('t1.kanban')->eq($executionID)
->andWhere('t1.`type`')->eq($browseType)
->beginIF(isset($execution->type) and $execution->type == 'kanban')
->andWhere('t3.deleted')->eq(0)
->andWhere('t4.deleted')->eq(0)
->fi()
->groupBy('columnType')
->orderBy('column_asc')
->fetchAll('columnType');
$cardGroup = array();
$actions = array('setColumn', 'setWIP');
foreach($columns as $column)
{
if(empty($column->cards)) continue;
@@ -1482,6 +1499,7 @@ class kanbanModel extends model
$laneData['name'] = (($groupBy == 'pri' or $groupBy == 'severity') and $laneID) ? $this->lang->$browseType->$groupBy . ':' . $lane->name : $lane->name;
$laneData['color'] = $lane->color;
$laneData['order'] = $lane->order;
$laneData['type'] = $browseType;
$laneData['defaultCardType'] = $browseType;
/* Construct kanban column data. */
@@ -1492,6 +1510,13 @@ class kanbanModel extends model
if(in_array($column->columnType, array('testing', 'tested'))) $parentColumn = 'test';
if(in_array($column->columnType, array('fixing', 'fixed'))) $parentColumn = 'resolving';
/* Judge column action priv. */
$column->actions = array();
foreach($actions as $action)
{
if($this->isClickable($column, $action)) $column->actions[] = $action;
}
$columnData[$column->column]['id'] = $column->column;
$columnData[$column->column]['type'] = $column->columnType;
$columnData[$column->column]['name'] = $column->columnName;
@@ -1500,6 +1525,7 @@ class kanbanModel extends model
$columnData[$column->column]['laneType'] = $browseType;
$columnData[$column->column]['asParent'] = in_array($column->columnType, array('develop', 'test', 'resolving')) ? true : false;
$columnData[$column->column]['parentType'] = $parentColumn;
$columnData[$column->column]['actions'] = $column->actions;
$cardOrder = 1;
$objects = zget($cardGroup, $column->columnType, array());
@@ -1519,6 +1545,10 @@ class kanbanModel extends model
$cardData['deadline'] = $browseType == 'story' ? '' : $object->deadline;
$cardData['severity'] = $browseType == 'bug' ? $object->severity : '';
if($lane->type == 'story') $cardData['menus'] = $storyCardMenu[$object->id];
if($lane->type == 'bug') $cardData['menus'] = $bugCardMenu[$object->id];
if($lane->type == 'task') $cardData['menus'] = $taskCardMenu[$object->id];
if($browseType == 'task')
{
$cardData['name'] = $object->name;
@@ -3115,7 +3145,20 @@ class kanbanModel extends model
*/
public function moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0)
{
$fromCellCards = $this->dao->select('cards')->from(TABLE_KANBANCELL)->where('lane')->eq($fromLaneID)->andWhere('`column`')->eq($fromColID)->fetch('cards');
$groupBy = ($this->session->execGroupBy and $this->app->tab == 'execution') ? $this->session->execGroupBy : '';
$fromCell = $this->dao->select('cards, lane')->from(TABLE_KANBANCELL)
->where('`column`')->eq($fromColID)
->beginIF(!$groupBy or $groupBy == 'default')->andWhere('lane')->eq($fromLaneID)->fi()
->beginIF($groupBy and $groupBy != 'default')
->andWhere('type')->eq($this->session->execLaneType)
->andWhere('cards')->like("%,$cardID,%")
->fi()
->fetch();
if($groupBy and $groupBy != 'default') $fromLaneID = $toLaneID = $fromCell->lane;
$fromCellCards = $fromCell->cards;
$toCell = $this->dao->select('*')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch();
$toCellCards = $this->dao->select('cards')->from(TABLE_KANBANCELL)->where('lane')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->fetch('cards');
+7 -1
View File
@@ -2486,7 +2486,13 @@ class projectModel extends model
$project = $this->getByID($objectID);
$model = 'scrum';
if($project) $model = $project->model;
if($project and $project->model == 'waterfall') $model = $project->model;
if($project and $project->model == 'kanban')
{
$model = $project->model . 'Project';
$lang->executionCommon = $lang->project->kanban;
}
if(isset($lang->$model))
{
+19 -2
View File
@@ -50,14 +50,32 @@ $config->story->custom->createFields = $config->story->list->customCreateFi
$config->story->custom->batchCreateFields = 'module,plan,spec,pri,estimate,review,%s';
$config->story->custom->batchEditFields = 'branch,module,plan,estimate,pri,source,stage,closedBy,closedReason';
global $lang, $app;
$config->story->datatable = new stdclass();
$config->story->datatable->defaultField = array('id', 'pri', 'title', 'plan', 'openedBy', 'assignedTo', 'estimate', 'status', 'stage', 'taskCount', 'actions');
if($app->tab == 'execution')
{
$config->story->datatable->defaultField = array('id','order', 'pri', 'title', 'plan', 'openedBy', 'assignedTo', 'estimate', 'status', 'stage', 'taskCount', 'actions');
}
else
{
$config->story->datatable->defaultField = array('id', 'pri', 'title', 'plan', 'openedBy', 'assignedTo', 'estimate', 'status', 'stage', 'taskCount', 'actions');
}
$config->story->datatable->fieldList['id']['title'] = 'idAB';
$config->story->datatable->fieldList['id']['fixed'] = 'left';
$config->story->datatable->fieldList['id']['width'] = '60';
$config->story->datatable->fieldList['id']['required'] = 'yes';
if($app->tab == 'execution')
{
$config->story->datatable->fieldList['order']['title'] = 'order';
$config->story->datatable->fieldList['order']['fixed'] = 'left';
$config->story->datatable->fieldList['order']['width'] = '60';
$config->story->datatable->fieldList['order']['sort'] = 'no';
$config->story->datatable->fieldList['order']['required'] = 'no';
$config->story->datatable->fieldList['order']['name'] = $this->lang->story->order;
}
$config->story->datatable->fieldList['pri']['title'] = 'priAB';
$config->story->datatable->fieldList['pri']['fixed'] = 'left';
$config->story->datatable->fieldList['pri']['width'] = '50';
@@ -194,7 +212,6 @@ $config->story->datatable->fieldList['version']['fixed'] = 'no';
$config->story->datatable->fieldList['version']['width'] = '60';
$config->story->datatable->fieldList['version']['required'] = 'no';
global $lang, $app;
$config->story->datatable->fieldList['taskCount']['title'] = 'T';
$config->story->datatable->fieldList['taskCount']['fixed'] = 'no';
$config->story->datatable->fieldList['taskCount']['width'] = '30';
+23 -15
View File
@@ -80,9 +80,9 @@ class story extends control
{
$this->loadModel('kanban');
$regionPairs = $this->kanban->getRegionPairs($execution->id, 0, 'execution');
$regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs);
$regionID = !empty($output['regionID']) ? $output['regionID'] : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'story');
$laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs);
$laneID = !empty($output['laneID']) ? $output['laneID'] : key($lanePairs);
$this->view->executionType = $execution->type;
$this->view->regionID = $regionID;
@@ -276,7 +276,7 @@ class story extends control
$title = $oldBug->title;
$keywords = $oldBug->keywords;
$spec = $oldBug->steps;
$pri = $oldBug->pri;
$pri = !empty($oldBug->pri) ? $oldBug->pri : '3';
if(strpos($oldBug->mailto, $oldBug->openedBy) === false)
{
$mailto = $oldBug->mailto . $oldBug->openedBy . ',';
@@ -407,10 +407,13 @@ class story extends control
if($execution->type == 'kanban')
{
$this->loadModel('kanban');
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
parse_str($extra, $output);
$regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution');
$regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs);
$regionID = !empty($output['regionID']) ? $output['regionID'] : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'story');
$laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs);
$laneID = !empty($output['laneID']) ? $output['laneID'] : key($lanePairs);
$this->view->regionID = $regionID;
$this->view->laneID = $laneID;
@@ -680,9 +683,9 @@ class story extends control
if(isonlybody())
{
$execution = $this->execution->getByID($this->session->execution);
if($this->app->tab == 'execution' and $execution->type == 'kanban' and $kanbanGroup == 'default')
if($this->app->tab == 'execution' and $execution->type == 'kanban')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', 0, $kanbanGroup);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
@@ -1052,10 +1055,12 @@ class story extends control
if(isonlybody())
{
$execution = $this->execution->getByID($this->session->execution);
if($this->app->tab == 'execution' and $execution->type == 'kanban' and $this->app->tab == 'execution')
if($this->app->tab == 'execution' and $execution->type == 'kanban')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
@@ -1358,8 +1363,10 @@ class story extends control
if($this->app->tab == 'execution' and $execution->type == 'kanban')
{
$this->loadModel('kanban')->updateLane($this->session->execution, 'story', $storyID);
$kanbanData = $this->kanban->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
@@ -1707,10 +1714,11 @@ class story extends control
if(isonlybody())
{
$execution = $this->execution->getByID($this->session->execution);
if($this->app->tab == 'execution' and $execution->type == 'kanban' and $kanbanGroup == 'default')
if($this->app->tab == 'execution' and $execution->type == 'kanban')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$kanbanData = $this->loadModel('kanban')->getRDKanban($this->session->execution, $execLaneType, 'id_desc', 0, $kanbanGroup);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
+1
View File
@@ -67,6 +67,7 @@ $lang->story->toTask = 'Convert to Task';
$lang->story->batchToTask = 'Batch Convert to Task';
$lang->story->convertRelations = 'Convert Relations';
$lang->story->undetermined = 'undetermined';
$lang->story->order = 'Order';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Change {$lang->SRCommon}";
+1
View File
@@ -67,6 +67,7 @@ $lang->story->toTask = '转任务';
$lang->story->batchToTask = '批量转任务';
$lang->story->convertRelations = '换算关系';
$lang->story->undetermined = '待定';
$lang->story->order = '排序';
$lang->story->editAction = "编辑{$lang->SRCommon}";
$lang->story->changeAction = "变更{$lang->SRCommon}";
+105 -11
View File
@@ -3807,7 +3807,7 @@ class storyModel extends model
* @access public
* @return string
*/
public function buildOperateMenu($story, $type = 'view')
public function buildOperateMenu($story, $type = 'view', $execution = '')
{
$menu = '';
$params = "storyID=$story->id";
@@ -3885,6 +3885,63 @@ class storyModel extends model
$menu .= $this->buildMenu('story', 'delete', $params, $story, 'button', 'trash', 'hiddenwin', 'showinonlybody', true);
}
if($type == 'execution')
{
$hasDBPriv = common::hasDBPriv($execution, 'execution');
$canBeChanged = common::canModify('execution', $execution);
if($canBeChanged)
{
$param = "executionID={$execution->id}&story={$story->id}&moduleID={$story->module}";
$story->reviewer = isset($story->reviewer) ? $story->reviewer : array();
$story->notReview = isset($story->notReview) ? $story->notReview : array();
if(common::hasPriv('story', 'review'))
{
$reviewDisabled = in_array($this->app->user->account, $story->notReview) and ($story->status == 'draft' or $story->status == 'changed') ? '' : 'disabled';
$story->from = 'execution';
$menu .= common::printIcon('story', 'review', "story={$story->id}&from=story", $story, 'list', 'search', '', $reviewDisabled, false, "data-group=execution");
}
if(common::hasPriv('story', 'recall'))
{
$recallDisabled = empty($story->reviewedBy) and strpos('draft,changed', $story->status) !== false and !empty($story->reviewer) ? '' : 'disabled';
$menu .= common::printIcon('story', 'recall', "story={$story->id}", $story, 'list', 'undo', 'hiddenwin', $recallDisabled, '', '', $this->lang->story->recall);
}
$this->lang->task->create = $this->lang->execution->wbs;
$toTaskDisabled = strpos('draft,closed', $story->status) !== false ? 'disabled' : '';
if(commonModel::isTutorialMode())
{
$wizardParams = helper::safe64Encode($param);
$menu .= html::a(helper::createLink('tutorial', 'wizard', "module=task&method=create&params=$wizardParams"), "<i class='icon-plus'></i>",'', "class='btn btn-task-create' title='{$this->lang->execution->wbs}' data-app='execution'");
}
else
{
if($hasDBPriv) $menu .= common::printIcon('task', 'create', $param, '', 'list', 'plus', '', 'btn-task-create ' . $toTaskDisabled);
}
$this->lang->task->batchCreate = $this->lang->execution->batchWBS;
if($hasDBPriv) $menu .= common::printIcon('task', 'batchCreate', "executionID={$execution->id}&story={$story->id}", '', 'list', 'pluses', '', $toTaskDisabled);
$this->lang->testcase->batchCreate = $this->lang->testcase->create;
if($hasDBPriv and common::hasPriv('testcase', 'create'))
{
$menu .= html::a(helper::createLink('testcase', 'create', "productID=$story->product&branch=$story->branch&moduleID=$story->module&form=&param=0&storyID=$story->id"), '<i class="icon-testcase-create icon-sitemap"></i>', '', "class='btn' title='{$this->lang->testcase->create}' data-app='qa'");
}
if($canBeChanged and common::hasPriv('execution', 'storyEstimate', $execution))
{
$menu .= common::printIcon('execution', 'storyEstimate', "executionID=$execution->id&storyID=$story->id", '', 'list', 'estimate', '', 'iframe', true, "data-width='600px'");
}
if($canBeChanged and common::hasPriv('execution', 'unlinkStory', $execution))
{
$menu .= common::printIcon('execution', 'unlinkStory', "executionID=$execution->id&storyID=$story->id&confirm=no", '', 'list', 'unlink', 'hiddenwin');
}
}
}
return $menu;
}
@@ -4048,10 +4105,17 @@ class storyModel extends model
* @access public
* @return void
*/
public function printCell($col, $story, $users, $branches, $storyStages, $modulePairs = array(), $storyTasks = array(), $storyBugs = array(), $storyCases = array(), $mode = 'datatable', $storyType = 'story')
public function printCell($col, $story, $users, $branches, $storyStages, $modulePairs = array(), $storyTasks = array(), $storyBugs = array(), $storyCases = array(), $mode = 'datatable', $storyType = 'story', $execution = '', $isShowBranch = '')
{
$module = $this->app->rawModule == 'product' ? 'story' : $this->app->rawModule;
$canView = common::hasPriv($module, 'view');
$tab = $this->app->tab;
$storyLink = $tab == 'execution' ? helper::createLink('story', 'view', "storyID=$story->id&version=$story->version&from=execution&param=$execution->id") : helper::createLink($module, 'view', "storyID=$story->id");
$account = $this->app->user->account;
/* Check the product is closed. */
$canBeChanged = common::canBeChanged('story', $story);
$canOrder = common::hasPriv('execution', 'storySort');
$canBatchEdit = common::hasPriv('story', 'batchEdit');
$canBatchClose = common::hasPriv('story', 'batchClose');
@@ -4062,15 +4126,25 @@ class storyModel extends model
$canBatchChangePlan = common::hasPriv('story', 'batchChangePlan');
$canBatchAssignTo = common::hasPriv('story', 'batchAssignTo');
$canBatchUnlinkStory = common::hasPriv('projectstory', 'batchUnlinkStory');
$canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory');
$canBatchAction = ($canBatchEdit or $canBatchClose or $canBatchReview or $canBatchChangeStage or $canBatchChangeBranch or $canBatchChangeModule or $canBatchChangePlan or $canBatchAssignTo or $canBatchUnlinkStory);
if($tab == 'execution')
{
$checkObject = new stdclass();
$checkObject->execution = $execution->id;
$canBatchToTask = common::hasPriv('story', 'batchToTask', $checkObject);
}
$module = $this->app->rawModule == 'projectstory' ? 'projectstory' : 'story';
$canView = common::hasPriv($module, 'view');
$tab = $this->app->rawModule == 'projectstory' ? 'project' : 'product';
$storyLink = helper::createLink($module, 'view', "storyID=$story->id");
$account = $this->app->user->account;
$id = $col->id;
if($tab == 'execution')
{
$canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchClose or $canBatchChangeStage or $canBatchUnlink or $canBatchToTask));
}
else
{
$canBatchAction = ($canBatchEdit or $canBatchClose or $canBatchReview or $canBatchChangeStage or $canBatchChangeBranch or $canBatchChangeModule or $canBatchChangePlan or $canBatchAssignTo or $canBatchUnlinkStory);
}
$id = $col->id;
if($col->show)
{
$class = "c-{$id}";
@@ -4141,6 +4215,10 @@ class storyModel extends model
{
$class .= ' text-center';
}
elseif($id == 'order')
{
$class = 'sort-handler c-sort';
}
echo "<td class='" . $class . "' title='$title' style='$style'>";
if($this->config->edition != 'open') $this->loadModel('flow')->printFlowCell('story', $story, $id);
@@ -4156,16 +4234,23 @@ class storyModel extends model
printf('%03d', $story->id);
}
break;
case 'order':
echo "<i class='icon-move'>";
break;
case 'pri':
echo "<span class='label-pri label-pri-" . $story->pri . "' title='" . zget($this->lang->story->priList, $story->pri, $story->pri) . "'>";
echo zget($this->lang->story->priList, $story->pri, $story->pri);
echo "</span>";
break;
case 'title':
if($this->app->tab == 'project')
if($tab == 'project')
{
$showBranch = isset($this->config->projectstory->story->showBranch) ? $this->config->projectstory->story->showBranch : 1;
}
elseif($tab == 'execution')
{
if($isShowBranch) $showBranch = isset($this->config->execution->story->showBranch) ? $this->config->execution->story->showBranch : 1;
}
else
{
$showBranch = isset($this->config->product->browse->showBranch) ? $this->config->product->browse->showBranch : 1;
@@ -4292,7 +4377,16 @@ class storyModel extends model
echo $story->version;
break;
case 'actions':
echo $this->buildOperateMenu($story, 'browse');
if($tab == 'execution')
{
$menuType = 'execution';
}
else
{
$menuType = 'browse';
$execution = '';
}
echo $this->buildOperateMenu($story, $menuType, $execution);
break;
}
echo '</td>';
+53 -33
View File
@@ -90,7 +90,7 @@ class task extends control
if($execution->type == 'kanban')
{
$regionPairs = $this->kanban->getRegionPairs($execution->id, 0, 'execution');
$regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs);
$regionID = !empty($output['regionID']) ? $output['regionID'] : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'task');
$laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs);
@@ -139,7 +139,7 @@ class task extends control
/* if status is exists then this task has exists not new create. */
if($taskID['status'] == 'exists') continue;
$taskID = $taskID['id'];
$taskID = $taskID['id'];
$this->action->create('task', $taskID, 'Opened', '');
}
@@ -173,8 +173,10 @@ class task extends control
{
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->kanban->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, 0)"));
}
@@ -347,8 +349,10 @@ class task extends control
{
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, 0)"));
}
@@ -397,7 +401,7 @@ class task extends control
$this->loadModel('kanban');
$regionPairs = $this->kanban->getRegionPairs($executionID, 0, 'execution');
$regionID = isset($output['regionID']) ? $output['regionID'] : key($regionPairs);
$regionID = !empty($output['regionID']) ? $output['regionID'] : key($regionPairs);
$lanePairs = $this->kanban->getLanePairsByRegion($regionID, 'task');
$laneID = isset($output['laneID']) ? $output['laneID'] : key($lanePairs);
@@ -503,9 +507,9 @@ class task extends control
if(isonlybody())
{
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution' and $kanbanGroup == 'default')
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', 0, $kanbanGroup);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
@@ -738,9 +742,9 @@ class task extends control
{
$task = $this->task->getById($taskID);
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution' and $kanbanGroup == 'default')
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', 0, $kanbanGroup);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
@@ -988,9 +992,11 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1050,8 +1056,10 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
@@ -1184,9 +1192,11 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1272,9 +1282,11 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1328,8 +1340,10 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
@@ -1399,9 +1413,11 @@ class task extends control
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1562,9 +1578,11 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
@@ -1618,9 +1636,11 @@ class task extends control
$execution = $this->execution->getByID($task->execution);
if($execution->type == 'kanban' and $this->app->tab == 'execution')
{
$regionID = isset($output['regionID']) ? $output['regionID'] : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all', 'id_desc', $regionID);
$kanbanData = json_encode($kanbanData);
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
}
+3
View File
@@ -248,6 +248,9 @@ class testtask extends control
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID);
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk');
$execution = $this->loadModel('execution')->getByID($executionID);
if(!empty($execution) and $execution->type == 'kanban') $this->lang->testtask->execution = str_replace($this->lang->execution->common, $this->lang->kanban->common, $this->lang->testtask->execution);
/* Set menu. */
$productID = $this->product->saveState($productID, $this->products);
+1 -1
View File
@@ -4834,7 +4834,7 @@ class upgradeModel extends model
/* Project linked objects. */
$this->dao->update(TABLE_TASK)->set('project')->eq($projectID)->where('execution')->in($sprintIdList)->exec();
$this->dao->update(TABLE_BUILD)->set('project')->eq($projectID)->where('execution')->in($sprintIdList)->andWhere('project')->eq(0)->exec();
$this->dao->update(TABLE_BUG)->set('project')->eq($projectID)->where('execution')->in($sprintIdList)->andWhere('project')->eq(0)->exec();
$this->dao->update(TABLE_BUG)->set('project')->eq($projectID)->where('execution')->in($sprintIdList)->exec();
$this->dao->update(TABLE_DOC)->set('project')->eq($projectID)->set('type')->eq('execution')->where("lib IN(SELECT id from " . TABLE_DOCLIB . " WHERE type = 'project' and execution " . helper::dbIN($sprintIdList) . ')')->exec();
$this->dao->update(TABLE_DOCLIB)->set('project')->eq($projectID)->where('type')->eq('execution')->andWhere('execution')->in($sprintIdList)->exec();
$this->dao->update(TABLE_TESTTASK)->set('project')->eq($projectID)->where('execution')->in($sprintIdList)->exec();
+1 -1
View File
@@ -1,5 +1,5 @@
/*!
* ZUI: ZUI Kanban View - v1.10.0 - 2022-05-19
* ZUI: ZUI Kanban View - v1.10.0 - 2022-06-01
* http://openzui.com
* GitHub: https://github.com/easysoft/zui.git
* Copyright (c) 2022 cnezsoft.com; Licensed MIT
File diff suppressed because one or more lines are too long