Merge branch 'zentaopms_239'

This commit is contained in:
wangyidong
2022-11-08 08:41:28 +08:00
458 changed files with 9419 additions and 4940 deletions
+13 -15
View File
@@ -54,7 +54,7 @@ $config->execution->search['fields']['desc'] = $lang->task->desc;
$config->execution->search['fields']['assignedTo'] = $lang->task->assignedTo;
$config->execution->search['fields']['pri'] = $lang->task->pri;
if($app->tab == 'my' and $config->systemMode == 'new') $config->execution->search['fields']['project'] = $lang->task->project;
if($app->tab == 'my') $config->execution->search['fields']['project'] = $lang->task->project;
$config->execution->search['fields']['execution'] = $lang->task->execution;
$config->execution->search['fields']['module'] = $lang->task->module;
$config->execution->search['fields']['estimate'] = $lang->task->estimate;
@@ -89,7 +89,7 @@ $config->execution->search['params']['desc'] = array('operator' => 'in
$config->execution->search['params']['assignedTo'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['pri'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->task->priList);
if($app->tab == 'my' and $config->systemMode == 'new') $config->execution->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
if($app->tab == 'my') $config->execution->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->execution->search['params']['execution'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->execution->search['params']['module'] = array('operator' => 'belong', 'control' => 'select', 'values' => '');
$config->execution->search['params']['estimate'] = array('operator' => '=', 'control' => 'input', 'values' => '');
@@ -102,7 +102,7 @@ $config->execution->search['params']['closedReason'] = array('operator' => '='
$config->execution->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['finishedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['cancelBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['canceledBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['lastEditedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users');
@@ -124,7 +124,7 @@ $config->execution->all->search['module'] = 'execution';
$config->execution->all->search['fields']['name'] = $lang->execution->execName;
$config->execution->all->search['fields']['id'] = $lang->execution->execId;
$config->execution->all->search['fields']['status'] = $lang->execution->execStatus;
if($config->systemMode == 'new') $config->execution->all->search['fields']['project'] = $lang->execution->project;
$config->execution->all->search['fields']['project'] = $lang->execution->project;
$config->execution->all->search['fields']['PM'] = $lang->execution->owner;
$config->execution->all->search['fields']['openedBy'] = $lang->execution->openedBy;
$config->execution->all->search['fields']['openedDate'] = $lang->execution->openedDate;
@@ -140,7 +140,7 @@ $config->execution->all->search['fields']['teamCount'] = $lang->execution->
$config->execution->all->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->execution->all->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
$config->execution->all->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => array('') + $lang->execution->statusList);
if($config->systemMode == 'new') $config->execution->all->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->execution->all->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->execution->all->search['params']['PM'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->all->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->all->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
@@ -175,15 +175,16 @@ $config->execution->gantt->linkType['end']['end'] = 2;
$config->execution->gantt->linkType['begin']['end'] = 3;
$config->execution->datatable = new stdclass();
if($config->systemMode == 'new')
if(!isset($config->setCode) or $config->setCode == 1)
{
$config->execution->datatable->defaultField = array('id', 'name', 'project', 'status', 'PM', 'begin', 'end', 'estimate', 'consumed', 'left', 'progress', 'burn');
$config->execution->datatable->defaultField = array('id', 'name', 'code', 'project', 'PM', 'status', 'progress', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
}
else
{
$config->execution->datatable->defaultField = array('id', 'name', 'status', 'PM', 'begin', 'end', 'estimate', 'consumed', 'left', 'progress', 'burn');
$config->execution->datatable->defaultField = array('id', 'name', 'project', 'PM', 'status', 'progress', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
}
$config->execution->datatable->fieldList['id']['title'] = 'idAB';
$config->execution->datatable->fieldList['id']['fixed'] = 'left';
$config->execution->datatable->fieldList['id']['width'] = '70';
@@ -195,13 +196,10 @@ $config->execution->datatable->fieldList['name']['width'] = 'auto';
$config->execution->datatable->fieldList['name']['required'] = 'yes';
if($config->systemMode == 'new')
{
$config->execution->datatable->fieldList['project']['title'] = 'project';
$config->execution->datatable->fieldList['project']['fixed'] = 'no';
$config->execution->datatable->fieldList['project']['width'] = '128';
$config->execution->datatable->fieldList['project']['required'] = 'no';
}
$config->execution->datatable->fieldList['project']['title'] = 'project';
$config->execution->datatable->fieldList['project']['fixed'] = 'no';
$config->execution->datatable->fieldList['project']['width'] = '128';
$config->execution->datatable->fieldList['project']['required'] = 'no';
if(!isset($config->setCode) or $config->setCode == 1)
{
+175 -116
View File
@@ -41,15 +41,14 @@ class execution extends control
$this->loadModel('project');
if(defined('IN_UPGRADE') and IN_UPGRADE) return false;
if(!isset($this->app->user)) return;
if(isset($this->app->user))
$mode = $this->app->tab == 'execution' ? 'multiple' : '';
$this->executions = $this->execution->getPairs(0, 'all', "nocode,{$mode}");
$skipCreateStep = array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers', 'all');
if(!in_array($this->methodName, $skipCreateStep) and $this->app->tab == 'execution')
{
$this->executions = $this->execution->getPairs(0, 'all', 'nocode');
$skipCreateStep = array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers', 'all');
if(!in_array($this->methodName, $skipCreateStep) and $this->app->tab == 'execution')
{
if(!$this->executions and $this->methodName != 'index' and $this->methodName != 'create' and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('execution', 'create'));
}
if(!$this->executions and $this->methodName != 'index' and $this->methodName != 'create' and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('execution', 'create'));
}
}
@@ -84,11 +83,13 @@ class execution extends control
$childExecutions = $this->execution->getChildExecutions($executionID);
$teamMembers = $this->execution->getTeamMembers($executionID);
$actions = $this->loadModel('action')->getList($this->objectType, $executionID);
$project = $this->loadModel('project')->getByID($execution->project);
/* Set menu. */
$this->execution->setMenu($executionID, $buildID = 0, $extra);
/* Assign. */
$this->view->hidden = !empty($project->hasProduct) ? "" : 'hide';
$this->view->executions = $this->executions;
$this->view->execution = $execution;
$this->view->childExecutions = $childExecutions;
@@ -142,8 +143,12 @@ class execution extends control
array_unshift($recentExecutions, $executionID);
$recentExecutions = array_unique($recentExecutions);
$recentExecutions = array_slice($recentExecutions, 0, 5);
$this->setting->setItem($this->app->user->account . 'common.execution.recentExecutions', implode(',', $recentExecutions));
$this->setting->setItem($this->app->user->account . 'common.execution.lastExecution', $executionID);
$recentExecutions = join(',', $recentExecutions);
if(!$this->session->multiple)
{
if(!isset($this->config->execution->recentExecutions) or $this->config->execution->recentExecutions != $recentExecutions) $this->setting->updateItem($this->app->user->account . 'common.execution.recentExecutions', $recentExecutions);
if(!isset($this->config->execution->lastExecution) or $this->config->execution->lastExecution != $executionID) $this->setting->updateItem($this->app->user->account . 'common.execution.lastExecution', $executionID);
}
if($this->cookie->preExecutionID != $executionID)
{
@@ -185,9 +190,7 @@ class execution extends control
$sort = common::appendOrder($orderBy);
/* Header and position. */
$this->view->title = $execution->name . $this->lang->colon . $this->lang->execution->task;
$this->view->position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
$this->view->position[] = $this->lang->execution->task;
$this->view->title = $execution->name . $this->lang->colon . $this->lang->execution->task;
/* Load pager and get tasks. */
$this->app->loadClass('pager', $static = true);
@@ -249,7 +252,7 @@ class execution extends control
$this->view->setModule = true;
$this->view->canBeChanged = common::canModify('execution', $execution); // Determines whether an object is editable.
$this->view->showBranch = $showBranch;
$this->view->projectName = $this->config->systemMode == 'new' ? $this->loadModel('project')->getById($execution->project)->name . ' / ' . $execution->name : $execution->name;
$this->view->projectName = $this->loadModel('project')->getById($execution->project)->name . ' / ' . $execution->name;
$this->display();
}
@@ -530,8 +533,6 @@ class execution extends control
$this->view->title = $execution->name . $this->lang->colon . $this->lang->execution->importTask;
$this->view->pager = $pager;
$this->view->position[] = html::a(inlink('browse', "executionID=$toExecution"), $execution->name);
$this->view->position[] = $this->lang->execution->importTask;
$this->view->tasks2Imported = $tasks2ImportedList;
$this->view->executions = $executions;
$this->view->executionID = $execution->id;
@@ -637,7 +638,10 @@ class execution extends control
$bugs = $this->execution->getSearchBugs($products, $executionID, $bugQuery, $pager, 'id_desc');
}
/* Build the search form. */
$execution = $this->execution->getByID($executionID);
$project = $this->loadModel('project')->getByID($execution->project);
/* Build the search form. */
$this->config->bug->search['actionURL'] = $this->createLink('execution', 'importBug', "executionID=$executionID&browseType=bySearch&param=myQueryID");
$this->config->bug->search['queryID'] = $queryID;
if(!empty($products))
@@ -681,6 +685,12 @@ class execution extends control
unset($this->config->bug->search['fields']['resolvedDate']);
unset($this->config->bug->search['fields']['closedDate']);
unset($this->config->bug->search['fields']['branch']);
if(empty($project->hasProduct))
{
unset($this->config->bug->search['fields']['product']);
if($project->model !== 'scrum') unset($this->config->bug->search['fields']['plan']);
}
unset($this->config->bug->search['params']['resolvedBy']);
unset($this->config->bug->search['params']['closedBy']);
unset($this->config->bug->search['params']['status']);
@@ -704,7 +714,7 @@ class execution extends control
$this->view->browseType = $browseType;
$this->view->param = $param;
$this->view->users = $users;
$this->view->execution = $this->execution->getByID($executionID);
$this->view->execution = $execution;
$this->view->executionID = $executionID;
$this->view->requiredFields = explode(',', $this->config->task->create->requiredFields);
$this->display();
@@ -714,6 +724,7 @@ class execution extends control
* Browse stories of a execution.
*
* @param int $executionID
* @param string $storyType story|requirement
* @param string $orderBy
* @param string $type
* @param string $param
@@ -723,7 +734,7 @@ class execution extends control
* @access public
* @return void
*/
public function story($executionID = 0, $orderBy = 'order_desc', $type = 'all', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
public function story($executionID = 0, $storyType = 'story', $orderBy = 'order_desc', $type = 'all', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
{
/* Load these models. */
$this->loadModel('story');
@@ -732,6 +743,18 @@ class execution extends control
$this->app->loadLang('datatable');
$this->app->loadLang('testcase');
/* Change for requirement story title. */
if($storyType == 'requirement')
{
$this->lang->story->title = str_replace($this->lang->SRCommon, $this->lang->URCommon, $this->lang->story->title);
$this->lang->story->noStory = str_replace($this->lang->SRCommon, $this->lang->URCommon, $this->lang->story->noStory);
$this->lang->execution->createStory = str_replace($this->lang->SRCommon, $this->lang->URCommon, $this->lang->execution->createStory);
$this->config->product->search['fields']['title'] = $this->lang->story->title;
unset($this->config->product->search['fields']['plan']);
unset($this->config->product->search['fields']['stage']);
$this->story->replaceURLang($storyType);
}
$type = strtolower($type);
$param = $param;
$productID = 0;
@@ -746,7 +769,7 @@ class execution extends control
if($type == 'bymodule')
{
$module = $this->loadModel('tree')->getByID($param);
$productID = $module->root;
$productID = isset($module->root) ? $module->root : 0;
$_COOKIE['storyModuleParam'] = $param;
$_COOKIE['storyProductParam'] = 0;
@@ -781,8 +804,8 @@ class execution extends control
}
/* Save session. */
$this->app->session->set('storyList', $this->app->getURI(true), 'execution');
$this->app->session->set('executionStoryList', $this->app->getURI(true), 'execution');
$this->session->set('storyList', $this->app->getURI(true), $this->app->tab);
$this->session->set('executionStoryList', $this->app->getURI(true), 'execution');
/* Process the order by field. */
if(!$orderBy) $orderBy = $this->cookie->executionStoryOrder ? $this->cookie->executionStoryOrder : 'pri';
@@ -801,7 +824,7 @@ class execution extends control
if($this->app->getViewType() == 'xhtml') $recPerPage = 10;
$pager = new pager($recTotal, $recPerPage, $pageID);
$stories = $this->story->getExecutionStories($executionID, 0, 0, $sort, $type, $param, 'story', '', $pager);
$stories = $this->story->getExecutionStories($executionID, 0, 0, $sort, $type, $param, $storyType, '', $pager);
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', false);
@@ -839,7 +862,7 @@ class execution extends control
}
}
}
$actionURL = $this->createLink('execution', 'story', "executionID=$executionID&orderBy=$orderBy&type=bySearch&queryID=myQueryID");
$actionURL = $this->createLink('execution', 'story', "executionID=$executionID&storyType=$storyType&orderBy=$orderBy&type=bySearch&queryID=myQueryID");
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$branchOption = array();
foreach($branchGroups as $branches)
@@ -849,15 +872,26 @@ class execution extends control
$branchOption[$branchID] = $name;
}
}
$this->execution->buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, 'executionStory', $executionID);
$this->execution->buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, 'executionStory', $execution);
/* Header and position. */
$title = $execution->name . $this->lang->colon . $this->lang->execution->story;
$position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
$position[] = $this->lang->execution->story;
/* Get related tasks, bugs, cases count of each story. */
$storyIdList = array();
foreach($stories as $story)
{
$storyIdList[$story->id] = $story->id;
if(!empty($story->children))
{
foreach($story->children as $child) $storyIdList[$child->id] = $child->id;
}
}
/* Count T B C */
$storyIdList = array_keys($stories);;
$storyTasks = $this->loadModel('task')->getStoryTaskCounts($storyIdList, $executionID);
$storyBugs = $this->loadModel('bug')->getStoryBugCounts($storyIdList, $executionID);
$storyCases = $this->loadModel('testcase')->getStoryCaseCounts($storyIdList);
@@ -888,6 +922,16 @@ class execution extends control
$showModule = !empty($this->config->datatable->executionStory->showModule) ? $this->config->datatable->executionStory->showModule : '';
$modulePairs = $showModule ? $this->tree->getModulePairs($type == 'byproduct' ? $param : 0, 'story', $showModule) : array();
$createModuleLink = $storyType == 'story' ? 'createStoryLink' : 'createRequirementLink';
if(!$execution->hasProduct and !$execution->multiple)
{
$moduleTree = $this->tree->getTreeMenu($productID, 'story', $startModuleID = 0, array('treeModel', $createModuleLink), array('executionID' => $executionID, 'productID' => $productID), '', "&param=$param&storyType=$storyType");
}
else
{
$moduleTree = $this->tree->getProjectStoryTreeMenu($executionID, 0, array('treeModel', $createModuleLink));
}
/* Assign. */
$this->view->title = $title;
$this->view->position = $position;
@@ -898,10 +942,12 @@ class execution extends control
$this->view->allPlans = $allPlans;
$this->view->summary = $this->product->summary($stories);
$this->view->orderBy = $orderBy;
$this->view->storyType = $storyType;
$this->view->type = $this->session->executionStoryBrowseType;
$this->view->param = $param;
$this->view->isAllProduct = ($this->cookie->storyProductParam or $this->cookie->storyModuleParam or $this->cookie->storyBranchParam) ? false : true;
$this->view->moduleTree = $this->loadModel('tree')->getProjectStoryTreeMenu($executionID, 0, array('treeModel', 'createStoryLink'));
$createModuleLink = $storyType == 'story' ? 'createStoryLink' : 'createRequirementLink';
$this->view->moduleTree = $moduleTree;
$this->view->modulePairs = $modulePairs;
$this->view->tabID = 'story';
$this->view->storyTasks = $storyTasks;
@@ -967,12 +1013,22 @@ class execution extends control
$type = strtolower($type);
$queryID = ($type == 'bysearch') ? (int)$param : 0;
$execution = $this->commonAction($executionID);
$project = $this->loadModel('project')->getByID($execution->project);
$executionID = $execution->id;
$products = $this->product->getProducts($execution->id);
if($execution->hasProduct)
{
unset($this->config->bug->search['fields']['product']);
if($project->model != 'scrum')
{
unset($this->config->bug->search['fields']['plan']);
}
}
$productPairs = array('0' => $this->lang->product->all);
foreach($products as $productData) $productPairs[$productData->id] = $productData->name;
$this->lang->modulePageNav = $this->product->select($productPairs, $productID, 'execution', 'bug', $executionID, $branch);
if($execution->hasProduct) $this->lang->modulePageNav = $this->product->select($productPairs, $productID, 'execution', 'bug', $executionID, $branch);
/* Header and position. */
$title = $execution->name . $this->lang->colon . $this->lang->execution->bug;
@@ -1068,6 +1124,7 @@ class execution extends control
$this->view->orderBy = $orderBy;
$this->view->users = $users;
$this->view->productID = $productID;
$this->view->project = $project;
$this->view->branchID = empty($this->view->build->branch) ? $branch : $this->view->build->branch;
$this->view->memberPairs = $memberPairs;
$this->view->type = $type;
@@ -1120,8 +1177,12 @@ class execution extends control
$products = $this->product->getProducts($executionID, 'all', '', false);
if(count($products) == 1) $productID = key($products);
$execution = $this->execution->getByID($executionID);
$hasProduct = $this->dao->findByID($execution->project)->from(TABLE_PROJECT)->fetch('hasProduct');
$extra = $executionID;
$this->lang->modulePageNav = $this->product->select(array('0' => $this->lang->product->all) + $products, $productID, 'execution', 'testcase', $extra, $branchID);
if($hasProduct) $this->lang->modulePageNav = $this->product->select(array('0' => $this->lang->product->all) + $products, $productID, 'execution', 'testcase', $extra, $branchID);
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -1154,7 +1215,7 @@ class execution extends control
$this->view->pager = $pager;
$this->view->type = $type;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->execution = $this->execution->getByID($executionID);
$this->view->execution = $execution;
$this->view->moduleTree = $moduleTree;
$this->view->modules = $modules;
$this->view->moduleID = $moduleID;
@@ -1305,6 +1366,7 @@ class execution extends control
$this->view->position[] = html::a($this->createLink('execution', 'testtask', "executionID=$executionID"), $this->executions[$executionID]);
$this->view->position[] = $this->lang->testtask->common;
$this->view->execution = $execution;
$this->view->project = $this->loadModel('project')->getByID($execution->project);
$this->view->executionID = $executionID;
$this->view->executionName = $this->executions[$executionID];
$this->view->pager = $pager;
@@ -1658,7 +1720,8 @@ class execution extends control
$this->execution->updateProducts($executionID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('action')->create($this->objectType, $executionID, 'opened', '', join(',', $_POST['products']));
$comment = $project->hasProduct ? join(',', $_POST['products']) : '';
$this->loadModel('action')->create($this->objectType, $executionID, 'opened', '', $comment);
$message = $this->executeHooks($executionID);
if($message) $this->lang->saveSuccess = $message;
@@ -1721,23 +1784,26 @@ class execution extends control
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["RD"] = $this->config->user->moreLink;
$this->loadModel('product');
$allProducts = $this->config->systemMode == 'classic' ? $this->product->getPairs('noclosed') : $this->product->getProductPairsByProject($projectID, 'noclosed');
$copyProjects = $this->loadModel('project')->getPairsByProgram(isset($project->parent) ? $project->parent : '', 'noclosed', '', 'order_asc', '', isset($project->model) ? $project->model : '');
$allProducts = $this->product->getProductPairsByProject($projectID, 'noclosed');
$copyProjects = $this->loadModel('project')->getPairsByProgram(isset($project->parent) ? $project->parent : '', 'noclosed', '', 'order_asc', '', isset($project->model) ? $project->model : '', true);
$copyProjectID = ($projectID == 0) ? key($copyProjects) : $projectID;
$this->view->title = (($this->app->tab == 'execution') and ($this->config->systemMode == 'new')) ? $this->lang->execution->createExec : $this->lang->execution->create;
if(!empty($project->hasProduct)) $allProducts = array(0 => '') + $allProducts;
if(isset($project->hasProduct) and $project->hasProduct == 0) $this->lang->execution->PO = $this->lang->common->story . $this->lang->execution->owner;
$this->view->title = $this->app->tab == 'execution' ? $this->lang->execution->createExec : $this->lang->execution->create;
$this->view->position[] = $this->view->title;
$this->view->gobackLink = (isset($output['from']) and $output['from'] == 'global') ? $this->createLink('execution', 'all') : '';
$this->view->executions = array('' => '') + $this->execution->getList($projectID);
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->allProducts = array(0 => '') + $allProducts;
$this->view->allProducts = $allProducts;
$this->view->acl = $acl;
$this->view->plan = $plan;
$this->view->name = $name;
$this->view->code = $code;
$this->view->team = $team;
$this->view->teams = array(0 => '') + $this->execution->getCanCopyObjects((int)$projectID);
$this->view->allProjects = array(0 => '') + $this->project->getPairsByModel('all', 0, 'noclosed');
$this->view->allProjects = array(0 => '') + $this->project->getPairsByModel('all', 0, 'noclosed|nomultiple');
$this->view->copyProjects = $copyProjects;
$this->view->copyExecutions = array('' => '') + $this->execution->getList($copyProjectID);
$this->view->executionID = $executionID;
@@ -1749,7 +1815,7 @@ class execution extends control
$this->view->productPlans = array(0 => '') + $productPlans;
$this->view->whitelist = $whitelist;
$this->view->copyExecutionID = $copyExecutionID;
$this->view->branchGroups = isset($branchGroups) ? $branchGroups : $this->execution->getBranchByProduct(array_keys($products), $this->config->systemMode == 'new' ? $projectID : 0);
$this->view->branchGroups = isset($branchGroups) ? $branchGroups : $this->execution->getBranchByProduct(array_keys($products), $projectID);
$this->view->poUsers = $poUsers;
$this->view->pmUsers = $pmUsers;
$this->view->qdUsers = $qdUsers;
@@ -1875,7 +1941,7 @@ class execution extends control
$position[] = html::a($browseExecutionLink, $execution->name);
$position[] = $this->lang->execution->edit;
$allProducts = $this->config->systemMode == 'classic' ? $this->product->getPairs('noclosed', 0, $linkedProductIdList) : $this->product->getProducts($execution->project, 'noclosed', '', false, $linkedProductIdList);
$allProducts = $this->product->getProducts($execution->project, 'noclosed', '', false, $linkedProductIdList);
$allProducts = array(0 => '') + $allProducts;
$this->loadModel('productplan');
@@ -1922,6 +1988,7 @@ class execution extends control
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["RD"] = $this->config->user->moreLink;
$project = $this->project->getById($execution->project);
if(!$project->hasProduct) $this->lang->execution->PO = $this->lang->common->story . $this->lang->execution->owner;
$this->view->title = $title;
$this->view->position = $position;
@@ -1943,9 +2010,9 @@ class execution extends control
$this->view->unmodifiableBranches = $unmodifiableBranches;
$this->view->multiBranchProducts = $this->product->getMultiBranchPairs();
$this->view->productPlans = $productPlans;
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($linkedProducts), $this->config->systemMode == 'new' ? $execution->project : 0, 'noclosed', $linkedBranchList);
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($linkedProducts), $execution->project, 'noclosed', $linkedBranchList);
$this->view->teamMembers = $this->execution->getTeamMembers($executionID);
if($this->config->systemMode == 'new') $this->view->allProjects = $this->project->getPairsByModel($project->model, 0, 'noclosed', $project->id);
$this->view->allProjects = $this->project->getPairsByModel($project->model, 0, 'noclosed', $project->id);
$this->display();
}
@@ -2285,12 +2352,9 @@ class execution extends control
$execution->projectInfo = $this->loadModel('project')->getByID($execution->project);
if($this->config->systemMode == 'new')
{
$programList = array_filter(explode(',', $execution->projectInfo->path));
array_pop($programList);
$this->view->programList = $this->loadModel('program')->getPairsByList($programList);
}
$programList = array_filter(explode(',', $execution->projectInfo->path));
array_pop($programList);
$this->view->programList = $this->loadModel('program')->getPairsByList($programList);
if($execution->type == 'kanban' and defined('RUN_MODE') and RUN_MODE == 'api') return print($this->fetch('execution', 'kanban', "executionID=$executionID"));
@@ -2348,6 +2412,7 @@ class execution extends control
$pager = new pager(0, 30, 1);
$this->executeHooks($executionID);
if(!$execution->projectInfo->hasProduct) $this->lang->execution->PO = $this->lang->common->story . $this->lang->execution->owner;
$this->view->title = $this->lang->execution->view;
$this->view->position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
@@ -2437,6 +2502,8 @@ class execution extends control
foreach($plans as $plan) $allPlans += $plan;
}
$projectID = $this->loadModel('task')->getProjectID($execution->id);
$taskToOpen = !empty($_COOKIE['taskToOpen']) ? $_COOKIE['taskToOpen'] : 0;
setcookie('taskToOpen', 0, time() - 3600, $this->config->webRoot, '', $this->config->cookieSecure, true);
@@ -2453,7 +2520,8 @@ class execution extends control
$this->view->productNames = $productNames;
$this->view->productNum = count($products);
$this->view->branchID = $branchID;
$this->view->projectID = $this->loadModel('task')->getProjectID($execution->id);
$this->view->projectID = $projectID;
$this->view->project = $this->loadModel('project')->getByID($projectID);
$this->view->allPlans = $allPlans;
$this->view->kanbanData = $kanbanData;
$this->view->executionActions = $executionActions;
@@ -2533,21 +2601,26 @@ class execution extends control
$userList['closed']->realname = 'Closed';
$userList['closed']->avatar = '';
$this->view->title = $this->lang->execution->kanban;
$this->view->realnames = $this->loadModel('user')->getPairs('noletter');
$this->view->storyOrder = $orderBy;
$this->view->orderBy = 'id_asc';
$this->view->executionID = $executionID;
$this->view->productID = $productID;
$this->view->productNames = $productNames;
$this->view->productNum = count($products);
$this->view->allPlans = $allPlans;
$this->view->browseType = $browseType;
$this->view->kanbanGroup = $kanbanGroup;
$this->view->execution = $execution;
$this->view->groupBy = $groupBy;
$this->view->canBeChanged = $canBeChanged;
$this->view->userList = $userList;
$projectID = $execution->project;
$project = $this->dao->findByID($projectID)->from(TABLE_PROJECT)->fetch();
$hiddenPlan = $project->model !== 'scrum';
$this->view->title = $this->lang->execution->kanban;
$this->view->realnames = $this->loadModel('user')->getPairs('noletter');
$this->view->storyOrder = $orderBy;
$this->view->orderBy = 'id_asc';
$this->view->executionID = $executionID;
$this->view->productID = $productID;
$this->view->productNames = $productNames;
$this->view->productNum = count($products);
$this->view->allPlans = $allPlans;
$this->view->browseType = $browseType;
$this->view->kanbanGroup = $kanbanGroup;
$this->view->execution = $execution;
$this->view->groupBy = $groupBy;
$this->view->canBeChanged = $canBeChanged;
$this->view->userList = $userList;
$this->view->hiddenPlan = $hiddenPlan;
$this->display();
}
@@ -2673,6 +2746,7 @@ class execution extends control
$this->execution->setMenu($executionID);
$execution = $this->loadModel('execution')->getById($executionID);
$project = $this->loadModel('project')->getById($execution->project);
$tree = $this->execution->getTree($executionID);
/* Save to session. */
@@ -2685,13 +2759,13 @@ class execution extends control
if($type === 'json') return print(helper::jsonEncode4Parse($tree, JSON_HEX_QUOT | JSON_HEX_APOS));
$this->view->title = $this->lang->execution->tree;
$this->view->position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
$this->view->title = $this->lang->execution->tree;
$this->view->position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
$this->view->position[] = $this->lang->execution->tree;
$this->view->execution = $execution;
$this->view->executionID = $executionID;
$this->view->level = $type;
$this->view->tree = $this->execution->printTree($tree);
$this->view->tree = $this->execution->printTree($tree, $project->hasProduct);
$this->display();
}
@@ -2824,7 +2898,7 @@ class execution extends control
$this->execution->setMenu($executionID);
$execution = $this->loadModel('execution')->getById($executionID);
$stories = $this->loadModel('story')->getExecutionStories($executionID);
$stories = $this->loadModel('story')->getExecutionStories($executionID);
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', false);
/* Get execution's product. */
@@ -2961,7 +3035,7 @@ class execution extends control
$branches = $this->project->getBranchesByProject($executionID);
$linkedProductIdList = empty($branches) ? '' : array_keys($branches);
$allProducts = $this->config->systemMode == 'classic' ? $this->product->getPairs('noclosed', 0, $linkedProductIdList) : $this->product->getProductPairsByProject($execution->project, 'all', $linkedProductIdList);
$allProducts = $this->product->getProductPairsByProject($execution->project, 'all', $linkedProductIdList);
$linkedProducts = $this->product->getProducts($execution->id, 'all', '', true, $linkedProductIdList);
$linkedBranches = array();
$executionStories = $this->project->getStoriesByProject($executionID);
@@ -2996,8 +3070,8 @@ class execution extends control
$this->view->unmodifiableBranches = $unmodifiableBranches;
$this->view->linkedBranches = $linkedBranches;
$this->view->linkedStoryIDList = $linkedStoryIDList;
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($allProducts), $this->config->systemMode == 'new' ? $execution->project : 0, 'ignoreNormal|noclosed');
$this->view->allBranches = $this->execution->getBranchByProduct(array_keys($allProducts), $this->config->systemMode == 'new' ? $execution->project : 0, 'ignoreNormal');
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($allProducts), $execution->project, 'ignoreNormal|noclosed');
$this->view->allBranches = $this->execution->getBranchByProduct(array_keys($allProducts), $execution->project, 'ignoreNormal');
$this->display();
}
@@ -3137,11 +3211,12 @@ class execution extends control
}
/* Get projects, executions and products. */
$object = $this->project->getByID($objectID, $this->app->tab == 'project' ? 'project' : 'sprint,stage,kanban');
$object = $this->project->getByID($objectID, 'project,sprint,stage,kanban');
$products = $this->product->getProducts($objectID);
$queryID = ($browseType == 'bySearch') ? (int)$param : 0;
$browseLink = $this->session->executionStoryList;
if($this->app->tab == 'project') $browseLink = $this->createLink('projectstory', 'story', "objectID=$objectID");
if($this->app->tab == 'project' and $object->multiple) $browseLink = $this->createLink('projectstory', 'story', "objectID=$objectID");
if($object->type == 'kanban' && !$object->hasProduct) $this->lang->productCommon = $this->lang->project->common;
$this->session->set('storyList', $this->app->getURI(true), $this->app->tab); // Save session.
@@ -3229,7 +3304,7 @@ class execution extends control
/* Build the search form. */
$actionURL = $this->createLink($this->app->rawModule, 'linkStory', "objectID=$objectID&browseType=bySearch&queryID=myQueryID");
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$this->execution->buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, 'linkStory', $objectID);
$this->execution->buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, 'linkStory', $object);
if($browseType == 'bySearch')
{
@@ -3260,6 +3335,9 @@ class execution extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
$allStories = array_chunk($allStories, $pager->recPerPage);
$project = $object;
if(strpos('sprint,stage,kanban', $object->type) !== false) $project = $this->loadModel('project')->getByID($object->project);
/* Assign. */
$this->view->title = $object->name . $this->lang->colon . $this->lang->execution->linkStory;
$this->view->position[] = html::a($browseLink, $object->name);
@@ -3275,6 +3353,7 @@ class execution extends control
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->branchGroups = $branchGroups;
$this->view->browseLink = $browseLink;
$this->view->project = $project;
$this->display();
}
@@ -3494,12 +3573,8 @@ class execution extends control
*/
public function ajaxGetTeamMembers($objectID)
{
$type = 'execution';
if($this->config->systemMode == 'new')
{
$type = $this->dao->findById($objectID)->from(TABLE_PROJECT)->fetch('type');
if($type != 'project') $type = 'execution';
}
$type = $this->dao->findById($objectID)->from(TABLE_PROJECT)->fetch('type');
if($type != 'project') $type = 'execution';
$users = $this->loadModel('user')->getPairs('nodeleted|noclosed');
$members = $this->user->getTeamMemberPairs($objectID, $type);
@@ -3542,9 +3617,10 @@ class execution extends control
$projects = $this->loadModel('program')->getProjectList(0, 'all', 0, 'order_asc', null, 0, 0, true);
$executionGroups = $this->dao->select('*')->from(TABLE_EXECUTION)
->where('deleted')->eq(0)
->andWhere('multiple')->eq('1')
->andWhere('type')->in('sprint,stage,kanban')
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->beginIF($this->config->systemMode == 'new')->andWhere('project')->in(array_keys($projects))->fi()
->andWhere('project')->in(array_keys($projects))
->orderBy('id_desc')
->fetchGroup('project', 'id');
@@ -3554,33 +3630,19 @@ class execution extends control
->fetchGroup('root', 'account');
$projectPairs = array();
if($this->config->systemMode == 'new')
foreach($projects as $project)
{
foreach($projects as $project)
{
$executions = zget($executionGroups, $project->id, array());
if(isset($project->model) and $project->model == 'waterfall') ksort($executions);
$executions = zget($executionGroups, $project->id, array());
if(isset($project->model) and $project->model == 'waterfall') ksort($executions);
foreach($executions as $execution)
{
if(isset($orderedExecutions[$execution->parent]) and $project->model != 'waterfall') unset($orderedExecutions[$execution->parent]);
$execution->teams = zget($teams, $execution->id, array());
$orderedExecutions[$execution->id] = $execution;
}
$projectPairs[$project->id] = $project->name;
}
}
else
{
foreach($executionGroups as $projectID => $executions)
foreach($executions as $execution)
{
foreach($executions as $execution)
{
$execution->teams = zget($teams, $execution->id, array());
$orderedExecutions[$execution->id] = $execution;
}
if(isset($orderedExecutions[$execution->parent]) and $project->model != 'waterfall') unset($orderedExecutions[$execution->parent]);
$execution->teams = zget($teams, $execution->id, array());
$orderedExecutions[$execution->id] = $execution;
}
$projectPairs[$project->id] = $project->name;
}
$projectExecutions = array();
@@ -4031,7 +4093,7 @@ class execution extends control
$projectID = $this->dao->findByID($executionID)->from(TABLE_EXECUTION)->fetch('project');
$planStories = array_keys($planStory);
if($this->config->systemMode == 'new' and $executionID != $projectID) $this->execution->linkStory($projectID, $planStories, $planProducts);
if($executionID != $projectID) $this->execution->linkStory($projectID, $planStories, $planProducts);
$this->execution->linkStory($executionID, $planStories, $planProducts, $extra);
}
@@ -4070,7 +4132,7 @@ class execution extends control
$story = $this->story->getById($storyID, $version, true);
$story->files = $this->loadModel('file')->getByObject('story', $storyID);
$product = $this->dao->findById($story->product)->from(TABLE_PRODUCT)->fields('name, id, type')->fetch();
$product = $this->dao->findById($story->product)->from(TABLE_PRODUCT)->fields('name, id, type, shadow')->fetch();
$plan = $this->dao->findById($story->plan)->from(TABLE_PRODUCTPLAN)->fetch('title');
$bugs = $this->dao->select('id,title')->from(TABLE_BUG)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->fetchAll();
$fromBug = $this->dao->select('id,title')->from(TABLE_BUG)->where('toStory')->eq($storyID)->fetch();
@@ -4210,21 +4272,18 @@ class execution extends control
*/
public function ajaxGetProjectStartDate($executionID = 0)
{
if($this->config->systemMode == 'new')
$execution = $this->dao->select('id,project')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch();
$project = $this->dao->select('begin,end')->from(TABLE_PROJECT)->where('id')->eq($execution->project)->fetch();
if(empty($project))
{
$execution = $this->dao->select('id,project')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch();
$project = $this->dao->select('begin,end')->from(TABLE_PROJECT)->where('id')->eq($execution->project)->fetch();
if(empty($project))
{
echo '';
return false;
}
$date = array();
$date['begin'] = $project->begin;
$date['end'] = $project->end;
echo json_encode($date);
echo '';
return false;
}
$date = array();
$date['begin'] = $project->begin;
$date['end'] = $project->end;
echo json_encode($date);
}
/**
+2 -1
View File
@@ -1,4 +1,5 @@
#fromproject_chosen .chosen-single {width: 220px;}
#fromexecution_chosen .chosen-single {max-width: 220px;}
#fromexecution_chosen .chosen-drop {white-space: nowrap;}
.c-name {min-width: 200px;}
.c-hour {width: 80px;}
#importTaskForm {min-height: 350px;}
+13
View File
@@ -21,3 +21,16 @@ th.c-pri{width:50px;}
.switchBtn > i {padding-left: 7px;}
#main>.container {padding: 0 20px 20px 23px;}
#executionStoryForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
.table-children {border-left: 2px solid #cbd0db; border-right: 2px solid #cbd0db;}
.table tbody > tr.table-children.table-child-top {border-top: 2px solid #cbd0db;}
.table tbody > tr.table-children.table-child-bottom {border-bottom: 2px solid #cbd0db;}
.table td.has-child > a:not(.story-toggle) {max-width: 90%; max-width: calc(100% - 30px); display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.table td.has-child > .story-toggle {color: #838a9d; position: relative; top: 1px;}
.table td.has-child > .story-toggle:hover {color: #006af1; cursor: pointer;}
.table td.has-child > .story-toggle > .icon {font-size: 16px; display: inline-block; transition: transform .2s; -ms-transform: rotate(-90deg); -moz-transform: rotate(-90deg); -o-transform: rotate(-90deg); -webkit-transform: rotate(-90deg); transform: rotate(-90deg);}
.table td.has-child > .story-toggle > .icon:before {text-align: left;}
.table td.has-child > .story-toggle.collapsed > .icon {-ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -o-transform: rotate(90deg); -webkit-transform: rotate(90deg); transform: rotate(90deg);}
.table td.c-estimate {padding-right: 12px;}
.main-table tbody > tr.table-children > td:first-child::before {width: 3px;}
.table-footer {z-index: 1;}
+1 -1
View File
@@ -1,7 +1,7 @@
.table-group-btns {width: 200px;}
.table-footer,
.table-grouped {box-shadow: none !important;}
.table-footer {margin-left: 205px; margin-top: 10px;}
.table-footer {margin-top: 10px;}
.table-grouped > thead>tr>th.c-id,
.table-grouped > tbody>tr>td.c-id {padding-left: 15px;}
.table-grouped > tbody>tr>td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
+2 -2
View File
@@ -138,11 +138,11 @@ function loadBranches(product)
if($inputgroup.find('select').size() >= 2) $inputgroup.removeClass('has-branch').find('select:last').remove();
if($inputgroup.find('.chosen-container').size() >= 2) $inputgroup.find('.chosen-container:last').remove();
var projectID = (typeof(systemMode) != 'undefined' && systemMode == 'new') ? $('#project').val() : 0;
var projectID = $('#project').val();
if(typeof(projectID) == 'undefined') projectID = 0;
var index = $inputgroup.find('select:first').attr('id').replace('products' , '');
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val() + "&oldBranch=&param=active&projectID=" + projectID + "&withMainBranch=true"), function(data)
$.get(createLink('branch', 'ajaxGetBranches', "productID=" + $(product).val() + "&oldBranch=0&param=active&projectID=" + projectID + "&withMainBranch=true"), function(data)
{
if(data)
{
+12 -15
View File
@@ -42,29 +42,26 @@ $(function()
var adjustMainCol = function()
{
if(!isStage) $('.main-form .col-main').css('width', Math.max(250, Math.floor(($('#productsBox').outerWidth() - 50)/3) + 10));
$('.main-form .col-main').css('width', Math.max(250, Math.floor(($('#tplBoxWrapper').parent('td').outerWidth() - 50)/3) + 10));
};
adjustMainCol();
$(window).on('resize', adjustMainCol);
$('#teams_chosen').click(function()
{
if(systemMode == 'new')
$('#teams_chosen ul li').each(function(index)
{
$('#teams_chosen ul li').each(function(index)
if(index == 0)
{
if(index == 0)
{
var projectName = subString($(this).text(), 56);
$(this).text(projectName);
$(this).append(' <label class="label">' + projectCommon + '</label>');
}
else
{
$(this).prepend('&nbsp;&nbsp;&nbsp;');
}
})
}
var projectName = subString($(this).text(), 56);
$(this).text(projectName);
$(this).append(' <label class="label">' + projectCommon + '</label>');
}
else
{
$(this).prepend('&nbsp;&nbsp;&nbsp;');
}
})
})
$('#teams').change(function()
+43 -20
View File
@@ -37,33 +37,56 @@ $().ready(function()
$(function()
{
/* If the story of the product which linked the execution under the project, you don't allow to remove the product. */
$("#productsBox select[name^='products']").each(function()
$(document).on('change', '[name*=products]', function()
{
var isExistedProduct = $.inArray($(this).attr('data-last'), unmodifiableProducts);
var productType = $(this).attr('data-type');
if(isExistedProduct != -1 && productType == 'normal')
{
$(this).prop('disabled', true).trigger("chosen:updated");
var current = $(this).val();
var last = $(this).attr('data-last');
var lastBranch = $(this).attr('data-lastBranch') !== undefined ? $(this).attr('data-lastBranch') : 0;
var productTip = tip.replace('%s', linkedStoryIDList[$(this).attr('data-last')][0]);
$(this).siblings('div').find('span').attr('title', productTip);
$(this).attr('data-last', current);
var $branch = $(this).closest('.has-branch').find("[name^='branch']");
if($branch.length)
{
var branchID = $branch.val();
$(this).attr('data-lastBranch', branchID);
}
else
{
$(this).removeAttr('data-lastBranch');
}
if(current != last && $.inArray(last, unmodifiableProducts) != -1)
{
if(lastBranch != 0)
{
if($.inArray(lastBranch, unmodifiableBranches) != -1)
{
if(linkedStoryIDList[last][lastBranch]) bootbox.alert(unLinkProductTip.replace("%s", allProducts[last] + branchGroups[last][lastBranch]));
}
}
else
{
bootbox.alert(unLinkProductTip.replace("%s", allProducts[last]));
}
}
});
$("#productsBox select[name^='branch']").each(function()
$(document).on('change', '[name*=branch]', function()
{
var isExistedBranch = $.inArray($(this).attr('data-last'), unmodifiableBranches);
if(isExistedBranch != -1)
{
var $product = $(this).closest('.has-branch').find("[name^='products']");
if($.inArray($product.val(), unmodifiableProducts) != -1 && linkedStoryIDList[$product.val()][$(this).attr('data-last')])
{
$(this).prop('disabled', true).trigger("chosen:updated");
$product.prop('disabled', true).trigger("chosen:updated");
var current = $(this).val();
var last = $(this).attr('data-last');
$(this).attr('data-last', current);
var productTip = tip.replace('%s', linkedStoryIDList[$product.val()][$(this).attr('data-last')]);
$product.siblings('div').find('span').attr('title', productTip);
var $product = $(this).closest('.has-branch').find("[name^='products']");
$product.attr('data-lastBranch', current);
if($.inArray(last, unmodifiableBranches) != -1)
{
var productID = $product.val();
if($.inArray(productID, unmodifiableProducts) != -1 && linkedStoryIDList[productID][last])
{
bootbox.alert(tip.replace('%s', linkedStoryIDList[productID][last]));
}
}
});
+11 -14
View File
@@ -22,22 +22,19 @@ $(function()
{
$('#execution_chosen, #execution + .picker').click(function()
{
if(systemMode == 'new')
$('#execution_chosen ul li, #pickerDropMenu-pk_execution div a').each(function(index)
{
$('#execution_chosen ul li, #pickerDropMenu-pk_execution div a').each(function(index)
if(index == 0)
{
if(index == 0)
{
var projectName = subString($(this).text(), 56);
$(this).text(projectName);
$(this).append(' <label class="label">' + projectCommon + '</label>');
}
else
{
$(this).prepend('&nbsp;&nbsp;&nbsp;');
}
})
}
var projectName = subString($(this).text(), 56);
$(this).text(projectName);
$(this).append(' <label class="label">' + projectCommon + '</label>');
}
else
{
$(this).prepend('&nbsp;&nbsp;&nbsp;');
}
})
});
})
+21
View File
@@ -10,6 +10,27 @@ $(function()
{
var $cb = $(this);
$cb.closest('.product').toggleClass('checked', $cb.prop('checked'));
if($cb.prop('checked')) return true;
var productID = String($cb.val());
if($.inArray(productID, unmodifiableProducts) != -1)
{
var $branch = $cb.closest('.product').find('[name^=branch]');
if($branch.length)
{
var branchID = String($branch.val());
if($.inArray(branchID, unmodifiableBranches) != -1 && linkedStoryIDList[productID][branchID])
{
bootbox.alert(unLinkProductTip.replace("%s", allProducts[productID] + branchGroups[productID][branchID]));
}
}
else
{
bootbox.alert(unLinkProductTip.replace("%s", allProducts[productID]));
}
}
});
$("select[id^=branch]").change(function()
+28
View File
@@ -2,6 +2,34 @@ $(function()
{
if($('#storyList thead th.c-title').width() < 150) $('#storyList thead th.c-title').width(150);
if(isDropMenu)
{
$('#navbar .nav li').removeClass('active');
$("#navbar .nav li[data-id=" + storyType + ']').addClass('active');
$('#navbar .nav>li[data-id=story]').addClass('active');
$('#navbar .nav>li[data-id=story]>a').html($('.active [data-id=' + storyType + ']').text() + '<span class="caret"></span>');
}
$('#storyList td.has-child .story-toggle').each(function()
{
var $td = $(this).closest('td');
var labelWidth = 0;
if($td.find('.label').length > 0) labelWidth = $td.find('.label').width();
$td.find('a').eq(0).css('max-width', $td.width() - labelWidth - 60);
});
$(document).on('click', '.story-toggle', function(e)
{
var $toggle = $(this);
var id = $(this).data('id');
var isCollapsed = $toggle.toggleClass('collapsed').hasClass('collapsed');
$toggle.closest('[data-ride="table"]').find('tr.parent-' + id).toggle(!isCollapsed);
e.stopPropagation();
e.preventDefault();
});
$('#storyList').on('sort.sortable', function(e, data)
{
var list = '';
+6 -16
View File
@@ -146,8 +146,7 @@ $lang->execution->estimate = 'estimate';
$lang->execution->consumed = 'consumed';
$lang->execution->left = 'Left';
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "select Project/{$lang->execution->common} to copy its members";
if($this->config->systemMode == 'classic') $lang->execution->copyTeamTip = "select Project/{$lang->execution->common} to copy its members";
$lang->execution->copyTeamTip = "copy Project/project team members";
$lang->execution->start = 'Start';
$lang->execution->activate = 'Aktivieren';
@@ -195,16 +194,8 @@ $lang->execution->statusList['suspended'] = 'Ausgesetzt';
$lang->execution->statusList['closed'] = 'Geschlossen';
global $config;
if($config->systemMode == 'new')
{
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Execution ACL (for who can access the current project)';
}
else
{
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Execution ACL (for who can access the current project)';
}
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Project ACL (for who can access the current project)';
$lang->execution->kanbanAclList['private'] = 'Private';
$lang->execution->kanbanAclList['open'] = 'Inherited Project';
@@ -279,8 +270,8 @@ $lang->execution->importBug = 'Importiere Bugs';
$lang->execution->tree = 'Baum';
$lang->execution->treeTask = 'Aufgabe anzeigen';
$lang->execution->treeStory = 'Story anzeigen';
$lang->execution->treeOnlyTask = 'Show Task Only';
$lang->execution->treeOnlyStory = 'Show Story Only';
$lang->execution->treeViewTask = 'Tree View Task';
$lang->execution->treeViewStory = 'Tree View Story';
$lang->execution->storyKanban = 'Story Kanban';
$lang->execution->storySort = 'Story sortieren';
$lang->execution->importPlanStory = '' . $lang->executionCommon . ' wurde erstellt!\nMöchten Sie Storys aus dem Plan importieren?';
@@ -375,8 +366,7 @@ $lang->execution->noMembers = 'Keine Mitglieder. ';
$lang->execution->workloadTotal = "The cumulative workload ratio should not exceed 100, and the total workload under the current product is: %s";
// $lang->execution->linkProjectStoryTip = "(Link {$lang->SRCommon} comes from {$lang->SRCommon} linked under the execution)";
$lang->execution->linkAllStoryTip = "({$lang->SRCommon} has never been linked under the project, and can be directly linked with {$lang->SRCommon} of the product linked with the sprint/stage)";
if($config->systemMode == 'classic') $lang->execution->copyTeamTitle = "Wählen Sie ein {$lang->executionCommon} Team zum Kopieren.";
if($config->systemMode == 'new') $lang->execution->copyTeamTitle = "Wählen Sie ein {$lang->executionCommon} Team zum Kopieren.";
$lang->execution->copyTeamTitle = "Choose a {$lang->project->common} or {$lang->execution->common} Team to copy.";
/* Interactive prompts. */
$lang->execution->confirmDelete = "Möchten Sie {$lang->executionCommon}[%s] löschen?";
+6 -16
View File
@@ -146,8 +146,7 @@ $lang->execution->estimate = 'Estimate';
$lang->execution->consumed = 'Consumed';
$lang->execution->left = 'Left';
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "copy Project/{$lang->execution->common} team members";
if($this->config->systemMode == 'classic') $lang->execution->copyTeamTip = "copy Project/{$lang->executionCommon} team members";
$lang->execution->copyTeamTip = "copy Project/project team members";
$lang->execution->start = 'Start';
$lang->execution->activate = 'Activate';
@@ -195,16 +194,8 @@ $lang->execution->statusList['suspended'] = 'Suspended';
$lang->execution->statusList['closed'] = 'Closed';
global $config;
if($config->systemMode == 'new')
{
$lang->execution->aclList['private'] = 'Private (for team members and execution stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Project ACL (for who can access the current project)';
}
else
{
$lang->execution->aclList['private'] = 'Private (for team members and execution stakeholders)';
$lang->execution->aclList['open'] = "Public (Users who can visit {$lang->executionCommon} can access it.)";
}
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Project ACL (for who can access the current project)';
$lang->execution->kanbanAclList['private'] = 'Private';
$lang->execution->kanbanAclList['open'] = 'Inherited Project';
@@ -279,8 +270,8 @@ $lang->execution->importBug = 'Import Bug';
$lang->execution->tree = 'Tree';
$lang->execution->treeTask = 'Show Task Only';
$lang->execution->treeStory = 'Show Story Only';
$lang->execution->treeOnlyTask = 'Show Task Only';
$lang->execution->treeOnlyStory = 'Show Story Only';
$lang->execution->treeViewTask = 'Tree View Task';
$lang->execution->treeViewStory = 'Tree View Story';
$lang->execution->storyKanban = 'Story Kanban';
$lang->execution->storySort = 'Rank Story';
$lang->execution->importPlanStory = $lang->executionCommon . ' is created!\nDo you want to import stories that have been linked to the plan? The stories in the draft will be automatically filtered out when imported.';
@@ -375,8 +366,7 @@ $lang->execution->noMembers = 'No team members yet. ';
$lang->execution->workloadTotal = "The cumulative workload ratio should not exceed 100, and the total workload under the current product is: %s";
// $lang->execution->linkProjectStoryTip = "(Link {$lang->SRCommon} comes from {$lang->SRCommon} linked under the execution)";
$lang->execution->linkAllStoryTip = "({$lang->SRCommon} has never been linked under the execution, and can be directly linked with {$lang->SRCommon} of the product linked with the sprint/stage)";
if($config->systemMode == 'classic') $lang->execution->copyTeamTitle = "Choose a {$lang->execution->common} Team to copy.";
if($config->systemMode == 'new') $lang->execution->copyTeamTitle = "Choose a {$lang->project->common} or {$lang->execution->common} Team to copy.";
$lang->execution->copyTeamTitle = "Choose a {$lang->project->common} or {$lang->execution->common} Team to copy.";
/* Interactive prompts. */
$lang->execution->confirmDelete = "Do you want to delete the {$lang->executionCommon}[%s]?";
+6 -16
View File
@@ -146,8 +146,7 @@ $lang->execution->estimate = 'estimate';
$lang->execution->consumed = 'consumed';
$lang->execution->left = 'Left';
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "select Project/{$lang->execution->common} to copy its members";
if($this->config->systemMode == 'classic') $lang->execution->copyTeamTip = "select Project/{$lang->execution->common} to copy its members";
$lang->execution->copyTeamTip = "copy Project/project team members";
$lang->execution->start = 'Démarrer';
$lang->execution->activate = 'Activer';
@@ -195,16 +194,8 @@ $lang->execution->statusList['suspended'] = 'Suspendu';
$lang->execution->statusList['closed'] = 'Fermé';
global $config;
if($config->systemMode == 'new')
{
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Execution ACL (for who can access the current project)';
}
else
{
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Execution ACL (for who can access the current project)';
}
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Project ACL (for who can access the current project)';
$lang->execution->kanbanAclList['private'] = 'Private';
$lang->execution->kanbanAclList['open'] = 'Inherited Project';
@@ -279,8 +270,8 @@ $lang->execution->importBug = 'Importer Bug';
$lang->execution->tree = 'Arboressence';
$lang->execution->treeTask = 'Seulement les Tâches';
$lang->execution->treeStory = 'Seulement les Stories';
$lang->execution->treeOnlyTask = 'Seulement les Tâches';
$lang->execution->treeOnlyStory = 'Seulement les Stories';
$lang->execution->treeViewTask = 'Seulement les Tâches';
$lang->execution->treeViewStory = 'Seulement les Stories';
$lang->execution->storyKanban = 'Story Kanban';
$lang->execution->storySort = 'Rang Story';
$lang->execution->importPlanStory = $lang->executionCommon . ' est créé!\nVoulez-vous importer des stories qui ont été ajoutées au Plan ?';
@@ -375,8 +366,7 @@ $lang->execution->noMembers = "Actuellement il n'y a aucun membre dan
$lang->execution->workloadTotal = "The cumulative workload ratio should not exceed 100, and the total workload under the current product is: %s";
// $lang->execution->linkProjectStoryTip = "(Link {$lang->SRCommon} comes from {$lang->SRCommon} linked under the execution)";
$lang->execution->linkAllStoryTip = "({$lang->SRCommon} has never been linked under the project, and can be directly linked with {$lang->SRCommon} of the product linked with the sprint/stage)";
if($config->systemMode == 'classic') $lang->execution->copyTeamTitle = "Choisissez une Equipe {$lang->executionCommon} à copier.";
if($config->systemMode == 'new') $lang->execution->copyTeamTitle = "Choisissez une Equipe {$lang->executionCommon} à copier.";
$lang->execution->copyTeamTitle = "Choose a {$lang->project->common} or {$lang->execution->common} Team to copy.";
/* Interactive prompts. */
$lang->execution->confirmDelete = "Voulez-vous réellement supprimer le {$lang->executionCommon}[%s] ?";
+5 -15
View File
@@ -102,9 +102,7 @@ $lang->execution->copyNoExecution = 'There are no ' . $lang->executionCommon . '
$lang->execution->noTeam = 'No team members at the moment';
$lang->execution->or = ' or ';
$lang->execution->selectProject = 'Please select project';
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "select Project/{$lang->execution->common} to copy its members";
if($this->config->systemMode == 'classic') $lang->execution->copyTeamTip = "select Project/{$lang->executionCommon} to copy its members";
$lang->execution->copyTeamTip = "select Project/{$lang->execution->common} to copy its members";
$lang->execution->start = 'Bắt đầu';
$lang->execution->activate = 'Kích hoạt';
@@ -148,16 +146,8 @@ $lang->execution->statusList['suspended'] = 'Đã đình chỉ';
$lang->execution->statusList['closed'] = 'Đã đóng';
global $config;
if($config->systemMode == 'new')
{
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Execution ACL (for who can access the current project)';
}
else
{
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = "Public (Users who can visit {$lang->executionCommon} can access it.)";
}
$lang->execution->aclList['private'] = 'Private (for team members and project stakeholders)';
$lang->execution->aclList['open'] = 'Inherited Execution ACL (for who can access the current project)';
$lang->execution->storyPoint = 'Story Point';
@@ -227,8 +217,8 @@ $lang->execution->importBug = 'Nhập Bug';
$lang->execution->tree = 'Cây';
$lang->execution->treeTask = 'Chỉ hiện nhiệm vụ';
$lang->execution->treeStory = 'Chỉ hiện câu chuyện';
$lang->execution->treeOnlyTask = 'Chỉ hiện nhiệm vụ';
$lang->execution->treeOnlyStory = 'Chỉ hiện câu chuyện';
$lang->execution->treeViewTask = 'Chỉ hiện nhiệm vụ';
$lang->execution->treeViewStory = 'Chỉ hiện câu chuyện';
$lang->execution->storyKanban = 'Kanban câu chuyện';
$lang->execution->storySort = 'Đánh giá câu chuyện';
$lang->execution->importPlanStory = $lang->executionCommon . ' được tạo!\nBạn có muốn nhập các câu chuyện mà đã liên kết đến kế hoạch này?';
+6 -16
View File
@@ -146,8 +146,7 @@ $lang->execution->estimate = '预计';
$lang->execution->consumed = '消耗';
$lang->execution->left = '剩余';
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "可以选择复制项目或{$lang->execution->common}团队的成员";
if($this->config->systemMode == 'classic') $lang->execution->copyTeamTip = "可以选择复制{$lang->executionCommon}团队的成员";
$lang->execution->copyTeamTip = "可以选择复制项目或{$lang->execution->common}团队的成员";
$lang->execution->start = "开始";
$lang->execution->activate = "激活";
@@ -195,16 +194,8 @@ $lang->execution->statusList['suspended'] = '已挂起';
$lang->execution->statusList['closed'] = '已关闭';
global $config;
if($config->systemMode == 'new')
{
$lang->execution->aclList['private'] = "私有(团队成员和项目负责人、干系人可访问)";
$lang->execution->aclList['open'] = "继承项目访问权限(能访问当前项目,即可访问)";
}
else
{
$lang->execution->aclList['private'] = "私有(团队成员和{$lang->executionCommon}负责人可访问)";
$lang->execution->aclList['open'] = "公开(有{$lang->executionCommon}视图权限即可访问)";
}
$lang->execution->aclList['private'] = "私有(团队成员和项目负责人、干系人可访问)";
$lang->execution->aclList['open'] = "继承项目访问权限(能访问当前项目,即可访问)";
$lang->execution->kanbanAclList['private'] = '私有';
$lang->execution->kanbanAclList['open'] = '继承项目';
@@ -279,8 +270,8 @@ $lang->execution->importBug = '导入Bug';
$lang->execution->tree = '树状图';
$lang->execution->treeTask = '只看任务';
$lang->execution->treeStory = "只看{$lang->SRCommon}";
$lang->execution->treeOnlyTask = '树状图只看任务';
$lang->execution->treeOnlyStory = "树状图只看{$lang->SRCommon}";
$lang->execution->treeViewTask = '树状图查看任务';
$lang->execution->treeViewStory = "树状图查看{$lang->SRCommon}";
$lang->execution->storyKanban = "{$lang->SRCommon}看板";
$lang->execution->storySort = "{$lang->SRCommon}排序";
$lang->execution->importPlanStory = '创建' . $lang->executionCommon . '成功!\n是否导入计划关联的相关' . $lang->SRCommon . '?导入时将自动过滤掉草稿状态的' . $lang->SRCommon . '。';
@@ -375,8 +366,7 @@ $lang->execution->noMembers = '暂时没有团队成员。';
$lang->execution->workloadTotal = "工作量占比累计不应当超过100, 当前产品下的工作量之和为%s";
// $lang->execution->linkProjectStoryTip = "(关联{$lang->SRCommon}来源于项目下所关联的{$lang->SRCommon})";
$lang->execution->linkAllStoryTip = "(项目下还未关联{$lang->SRCommon},可直接关联该{$lang->execution->common}所关联产品的{$lang->SRCommon})";
if($config->systemMode == 'classic') $lang->execution->copyTeamTitle = "选择一个{$lang->execution->common}团队";
if($config->systemMode == 'new') $lang->execution->copyTeamTitle = "选择一个{$lang->project->common}或{$lang->execution->common}团队";
$lang->execution->copyTeamTitle = "选择一个{$lang->project->common}或{$lang->execution->common}团队";
/* 交互提示。*/
$lang->execution->confirmDelete = "您确定删除{$lang->executionCommon}[%s]吗?";
+10 -22
View File
@@ -112,13 +112,11 @@ $lang->execution->batchCreateStory = "批量新建{$lang->SRCommon}";
$lang->execution->batchCreateTask = '批量建任務';
/* Fields of zt_team. */
$lang->execution->root = '源ID';
$lang->execution->estimate = '預計';
$lang->execution->consumed = '消耗';
$lang->execution->left = '剩餘';
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "可以選擇複製項目或{$lang->execution->common}團隊的成員";
if($this->config->systemMode == 'classic') $lang->execution->copyTeamTip = "可以選擇複製{$lang->executionCommon}團隊的成員";
$lang->execution->root = '源ID';
$lang->execution->estimate = '預計';
$lang->execution->consumed = '消耗';
$lang->execution->left = '剩餘';
$lang->execution->copyTeamTip = "可以選擇複製項目或{$lang->execution->common}團隊的成員";
$lang->execution->start = "開始";
$lang->execution->activate = "激活";
@@ -161,16 +159,8 @@ $lang->execution->statusList['suspended'] = '已掛起';
$lang->execution->statusList['closed'] = '已關閉';
global $config;
if($config->systemMode == 'new')
{
$lang->execution->aclList['private'] = "私有(團隊成員和項目負責人、干係人可訪問)";
$lang->execution->aclList['open'] = "繼承項目訪問權限(能訪問當前項目,即可訪問)";
}
else
{
$lang->execution->aclList['private'] = "私有(團隊成員和{$lang->executionCommon}負責人可訪問)";
$lang->execution->aclList['open'] = "公開(有{$lang->executionCommon}視圖權限即可訪問)";
}
$lang->execution->aclList['private'] = "私有(團隊成員和項目負責人、干係人可訪問)";
$lang->execution->aclList['open'] = "繼承項目訪問權限(能訪問當前項目,即可訪問)";
$lang->execution->storyPoint = '故事點';
@@ -239,8 +229,8 @@ $lang->execution->importBug = '導入Bug';
$lang->execution->tree = '樹狀圖';
$lang->execution->treeTask = '只看任務';
$lang->execution->treeStory = "只看{$lang->SRCommon}";
$lang->execution->treeOnlyTask = '樹狀圖只看任務';
$lang->execution->treeOnlyStory = "樹狀圖只看{$lang->SRCommon}";
$lang->execution->treeViewTask = '樹狀圖查看任務';
$lang->execution->treeViewStory = "樹狀圖查看{$lang->SRCommon}";
$lang->execution->storyKanban = "{$lang->SRCommon}看板";
$lang->execution->storySort = "{$lang->SRCommon}排序";
$lang->execution->importPlanStory = '創建' . $lang->executionCommon . '成功!\n是否導入計劃關聯的相關' . $lang->SRCommon . '?';
@@ -323,10 +313,8 @@ $lang->execution->noExecutions = "暫時沒有{$lang->execution->common}
$lang->execution->noPrintData = "暫無數據可打印";
$lang->execution->noMembers = '暫時沒有團隊成員。';
$lang->execution->workloadTotal = "工作量占比累計不應當超過100, 當前產品下的工作量之和為%s";
// $lang->execution->linkProjectStoryTip = "(關聯{$lang->SRCommon}來源於項目下所關聯的{$lang->SRCommon})";
$lang->execution->linkAllStoryTip = "(項目下還未關聯{$lang->SRCommon},可直接關聯該{$lang->execution->common}所關聯產品的{$lang->SRCommon})";
if($config->systemMode == 'classic') $lang->execution->copyTeamTitle = "選擇一個{$lang->execution->common}團隊來複制";
if($config->systemMode == 'new') $lang->execution->copyTeamTitle = "選擇一個{$lang->project->common}或{$lang->execution->common}團隊來複制";
$lang->execution->copyTeamTitle = "選擇一個{$lang->project->common}或{$lang->execution->common}團隊來複制";
/* 交互提示。*/
$lang->execution->confirmDelete = "您確定刪除{$lang->executionCommon}[%s]嗎?";
+280 -125
View File
@@ -92,7 +92,7 @@ class executionModel extends model
$this->session->set('execution', $executionID, $this->app->tab);
/* Unset story, bug, build and testtask if type is ops. */
if($execution and $execution->type == 'stage' and $this->config->systemMode == 'new')
if($execution and $execution->type == 'stage')
{
global $lang;
$this->app->loadLang('project');
@@ -131,8 +131,14 @@ class executionModel extends model
$this->cookie->executionMode = 'all';
}
if(empty($execution->hasProduct)) unset($this->lang->execution->menu->settings['subMenu']->products);
$this->lang->switcherMenu = $this->getSwitcher($executionID, $this->app->rawModule, $this->app->rawMethod);
common::setMenuVars('execution', $executionID);
$this->loadModel('project')->setNoMultipleMenu($executionID);
if(isset($this->lang->execution->menu->storyGroup)) unset($this->lang->execution->menu->storyGroup);
}
/**
@@ -156,31 +162,21 @@ class executionModel extends model
setCookie("lastExecution", $executionID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
$currentExecution = $this->getById($executionID);
if($this->config->systemMode == 'new')
if(isset($currentExecution->type) and $currentExecution->type == 'program') return;
if($currentExecution->project) $project = $this->loadModel('project')->getByID($currentExecution->project);
if(isset($project) and $project->model == 'waterfall')
{
if(isset($currentExecution->type) and $currentExecution->type == 'program') return;
if($currentExecution->project) $project = $this->loadModel('project')->getByID($currentExecution->project);
if(isset($project) and $project->model == 'waterfall')
{
$productID = $this->loadModel('product')->getProductIDByProject($project->id);
$productName = $this->dao->findByID($productID)->from(TABLE_PRODUCT)->fetch('name');
$currentExecution->name = $productName . '/' . $currentExecution->name;
}
$productID = $this->loadModel('product')->getProductIDByProject($project->id);
$productName = $this->dao->findByID($productID)->from(TABLE_PRODUCT)->fetch('name');
$currentExecution->name = $productName . '/' . $currentExecution->name;
}
$dropMenuLink = helper::createLink('execution', 'ajaxGetDropMenu', "executionID=$executionID&module=$currentModule&method=$currentMethod&extra=$extra");
$currentExecutionName = '';
if(isset($currentExecution->name)) $currentExecutionName = $currentExecution->name;
if($this->config->systemMode == 'classic')
{
$output = "<div class='btn-group header-btn' id='swapper'><button data-toggle='dropdown' type='button' class='btn' id='currentItem' title='{$currentExecutionName}'><span class='text'><i class='icon icon-sprint'></i> {$currentExecutionName}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div>";
}
$output = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem' title='{$currentExecutionName}'><span class='text'><i class='icon icon-{$this->lang->icons[$currentExecution->type]}'></i> {$currentExecutionName}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div></div>";
@@ -318,28 +314,24 @@ class executionModel extends model
*/
public function create($copyExecutionID = '')
{
$type = 'sprint';
$this->lang->execution->team = $this->lang->execution->teamname;
if($this->config->systemMode == 'new')
if(empty($_POST['project']))
{
if(empty($_POST['project']))
{
dao::$errors['message'][] = $this->lang->execution->projectNotEmpty;
return false;
}
if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($_POST['project'], $_POST['begin'], $_POST['end']);
if(dao::isError()) return false;
/* Determine whether to add a sprint or a stage according to the model of the execution. */
$project = $this->loadModel('project')->getByID($_POST['project']);
$type = 'sprint';
if($project) $type = zget($this->config->execution->modelList, $project->model, 'sprint');
$this->config->execution->create->requiredFields .= ',project';
dao::$errors['message'][] = $this->lang->execution->projectNotEmpty;
return false;
}
$this->checkBeginAndEndDate($_POST['project'], $_POST['begin'], $_POST['end']);
if(dao::isError()) return false;
/* Determine whether to add a sprint or a stage according to the model of the execution. */
$project = $this->loadModel('project')->getByID($_POST['project']);
$type = 'sprint';
if($project) $type = zget($this->config->execution->modelList, $project->model, 'sprint');
$this->config->execution->create->requiredFields .= ',project';
/* Judge workdays is legitimate. */
$workdays = helper::diffDate($_POST['end'], $_POST['begin']) + 1;
if(isset($_POST['days']) and $_POST['days'] > $workdays)
@@ -356,10 +348,10 @@ class executionModel extends model
->setDefault('openedVersion', $this->config->version)
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', helper::now())
->setDefault('team', substr($this->post->name, 0, 30))
->setDefault('team', $this->post->name)
->setDefault('parent', $this->post->project)
->setIF($this->post->heightType == 'auto', 'displayCards', 0)
->setIF(!isset($_POST['whitelist']), 'whitelist', '')
->setIF($this->config->systemMode == 'new', 'parent', $this->post->project)
->setIF($this->post->acl == 'open', 'whitelist', '')
->join('whitelist', ',')
->setDefault('type', $type)
@@ -367,6 +359,12 @@ class executionModel extends model
->remove('products, workDays, delta, branch, uid, plans, teams, teamMembers, contactListMenu, heightType')
->get();
if(!empty($sprint->parent))
{
$project = $this->loadModel('project')->getByID($sprint->parent);
$sprint->hasProduct = $project->hasProduct;
}
if(isset($_POST['heightType']) and $this->post->heightType == 'custom')
{
if(!$this->loadModel('kanban')->checkDisplayCards($sprint->displayCards)) return;
@@ -429,7 +427,7 @@ class executionModel extends model
$this->file->updateObjectID($this->post->uid, $executionID, 'execution');
/* Update the path. */
if($this->config->systemMode == 'new') $this->setTreePath($executionID);
$this->setTreePath($executionID);
$this->updateProducts($executionID);
@@ -453,7 +451,7 @@ class executionModel extends model
$this->dao->insert(TABLE_TEAM)->data($member)->exec();
$teamMembers[$account] = $member;
}
if($this->config->systemMode == 'new') $this->addProjectMembers($sprint->project, $teamMembers);
$this->addProjectMembers($sprint->project, $teamMembers);
/* Create doc lib. */
$this->app->loadLang('doc');
@@ -528,7 +526,7 @@ class executionModel extends model
if(in_array($execution->status, array('closed', 'suspended'))) $this->computeBurn($executionID);
if($this->config->systemMode == 'new' and (empty($execution->project) or $execution->project == $oldExecution->project)) $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end);
if(empty($execution->project) or $execution->project == $oldExecution->project) $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end);
if(dao::isError()) return false;
/* Child stage inherits parent stage permissions. */
@@ -814,7 +812,7 @@ class executionModel extends model
->checkIF($execution->begin != '', 'begin', 'date')
->checkIF($execution->end != '', 'end', 'date')
->checkIF($execution->end != '', 'end', 'ge', $execution->begin)
->checkIF((!empty($execution->name) and $this->config->systemMode == 'new'), 'name', 'unique', "id != $executionID and type in ('sprint','stage','kanban') and `project` = $projectID and `deleted` = '0'")
->checkIF(!empty($execution->name), 'name', 'unique', "id != $executionID and type in ('sprint','stage','kanban') and `project` = $projectID and `deleted` = '0'")
->checkIF(!empty($execution->code), 'code', 'unique', "id != $executionID and type in ('sprint','stage','kanban') and `deleted` = '0'")
->checkFlow()
->where('id')->eq($executionID)
@@ -912,7 +910,7 @@ class executionModel extends model
->remove('comment')
->get();
if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end);
$this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end);
if(dao::isError()) return false;
$execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->putoff['id'], $this->post->uid);
@@ -1173,7 +1171,7 @@ class executionModel extends model
}
/* The total workload of the first stage should not exceed 100%. */
if($type == 'create' or (empty($oldExecution) and $oldExecution->grade == 1))
if($type == 'create' or (!empty($oldExecution) and $oldExecution->grade == 1))
{
$oldPercentTotal = $this->dao->select('SUM(t2.percent) as total')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id')
@@ -1187,7 +1185,7 @@ class executionModel extends model
if($type == 'create') $percentTotal = $percent + $oldPercentTotal;
if(!empty($oldExecution) and $oldExecution->grade == 1) $percentTotal = $oldPercentTotal - $oldExecution->percent + $this->post->percent;
if($percentTotal >100)
if($percentTotal > 100)
{
dao::$errors['percent'] = sprintf($this->lang->execution->workloadTotal, $oldPercentTotal . '%');
return false;
@@ -1247,15 +1245,12 @@ class executionModel extends model
$currentExecution = $this->getById($executionID);
$currentExecutionName = $currentExecution->name;
if($this->config->systemMode == 'new')
{
$project = $this->loadModel('project')->getByID($currentExecution->project);
$project = $this->loadModel('project')->getByID($currentExecution->project);
if($project)
{
$projectNameTitle = $project->name . ' / ';
$projectNameSpan = "<span class='text'>{$project->name}</span> / ";
}
if($project)
{
$projectNameTitle = $project->name . ' / ';
$projectNameSpan = "<span class='text'>{$project->name}</span> / ";
}
}
@@ -1279,7 +1274,7 @@ class executionModel extends model
*
* @param int $projectID
* @param string $type all|sprint|stage|kanban
* @param string $mode all|noclosed|stagefilter or empty
* @param string $mode all|noclosed|stagefilter|withdelete|multiple or empty
* @access public
* @return array
*/
@@ -1306,22 +1301,46 @@ class executionModel extends model
$executions = $this->dao->select('*, IF(INSTR("done,closed", status) < 2, 0, 1) AS isDone, INSTR("doing,wait,suspended,closed", status) AS sortStatus')->from(TABLE_EXECUTION)
->where('deleted')->eq(0)
->andWhere('vision')->eq($this->config->vision)
->beginIF(!$this->session->multiple and $this->app->tab == 'execution')->andWhere('multiple')->eq('1')->fi()
->beginIF(strpos($mode, 'multiple') !== false)->andWhere('multiple')->eq('1')->fi()
->beginIF($type == 'all')->andWhere('type')->in('stage,sprint,kanban')->fi()
->beginIF($projectID and $this->config->systemMode == 'new')->andWhere('project')->eq($projectID)->fi()
->beginIF($type != 'all' and $this->config->systemMode == 'new')->andWhere('type')->eq($type)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->beginIF($type != 'all')->andWhere('type')->eq($type)->fi()
->beginIF(strpos($mode, 'withdelete') === false)->andWhere('deleted')->eq(0)->fi()
->beginIF(!$this->app->user->admin and strpos($mode, 'all') === false)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->orderBy($orderBy)
->fetchAll();
$pairs = array();
$pairs = array();
$noMultiples = array();
foreach($executions as $execution)
{
if(strpos($mode, 'noclosed') !== false and ($execution->status == 'done' or $execution->status == 'closed')) continue;
if(strpos($mode, 'stagefilter') !== false and isset($executionModel) and $executionModel == 'waterfall' and in_array($execution->attribute, array('request', 'design', 'review'))) continue; // Some stages of waterfall not need.
if(empty($execution->multiple)) $noMultiples[$execution->id] = $execution->project;
$pairs[$execution->id] = $execution->name;
}
if($noMultiples)
{
if(strpos($mode, 'hideMultiple') !== false)
{
foreach($noMultiples as $executionID => $projectID) $pairs[$executionID] = '';
}
else
{
$this->app->loadLang('project');
$noMultipleProjects = $this->dao->select('id, name')->from(TABLE_PROJECT)->where('id')->in($noMultiples)->fetchPairs('id', 'name');
foreach($noMultiples as $executionID => $projectID)
{
if(isset($noMultipleProjects[$projectID])) $pairs[$executionID] = $noMultipleProjects[$projectID] . "({$this->lang->project->disableExecution})";
}
}
}
if(strpos($mode, 'empty') !== false) $pairs[0] = '';
/* If the pairs is empty, to make sure there's an execution in the pairs. */
@@ -1525,6 +1544,7 @@ class executionModel extends model
->where('t1.type')->in('sprint,stage,kanban')
->andWhere('t1.deleted')->eq('0')
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.multiple')->eq('1')
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
->beginIF(!empty($executionQuery))->andWhere($executionQuery)->fi()
->beginIF($productID)->andWhere('t3.product')->eq($productID)->fi()
@@ -1589,7 +1609,7 @@ class executionModel extends model
if($param == 'skipParent')
{
if($execution->parent < 0 and $execution->type == 'stage') unset($executions[$key]);
if($this->config->systemMode == 'new' and $execution->projectName) $execution->name = $execution->projectName . ' / ' . $execution->name;
if($execution->projectName) $execution->name = $execution->projectName . ' / ' . $execution->name;
}
else
{
@@ -1636,7 +1656,7 @@ class executionModel extends model
->beginIF($limit)->limit($limit)->fi()
->fetchAll('id');
if(isset($project->model) and $project->model == 'waterfall')
if(isset($project->model) and $project->model == 'waterfall' and $project->hasProduct)
{
$executionList = array();
$executionProducts = $this->dao->select('t1.project,t1.product')->from(TABLE_PROJECTPRODUCT)->alias('t1')
@@ -1684,15 +1704,22 @@ class executionModel extends model
->where('t2.id')->in(array_keys($executions))
->fetchPairs('id', 'name');
}
else
{
$projects = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetchPairs('id', 'name');
}
if($pairs)
{
$this->app->loadLang('project');
$executionPairs = array();
foreach($executions as $execution)
{
$executionPairs[$execution->id] = '';
if(isset($projects[$execution->project])) $executionPairs[$execution->id] .= $projects[$execution->project] . ' / ';
$executionPairs[$execution->id] = '';
$executionPairs[$execution->id] .= isset($projects[$execution->project]) ? ($projects[$execution->project] . ' / ') : '';
$executionPairs[$execution->id] .= $execution->name;
if(empty($execution->multiple)) $executionPairs[$execution->id] = $projects[$execution->project] . "({$this->lang->project->disableExecution})";
}
$executions = $executionPairs;
}
@@ -1700,6 +1727,18 @@ class executionModel extends model
return $executions;
}
/**
* Get no multiple execution id.
*
* @param int $projectID
* @access public
* @return int
*/
public function getNoMultipleID($projectID)
{
return $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq($projectID)->andWhere('multiple')->eq(0)->andWhere('deleted')->eq(0)->fetch('id');
}
/**
* Create the link from module,method,extra
*
@@ -2142,12 +2181,14 @@ class executionModel extends model
public function getOrderedExecutions($executionID, $status, $num = 0)
{
$executionList = $this->getList($executionID, 'all', $status);
if(empty($executionIdList)) return $executionList;
if(empty($executionList)) return $executionList;
$executions = $mineExecutions = $otherExecutions = $closedExecutions = array();
foreach($executionList as $execution)
{
if(empty($execution->multiple)) continue;
if(!$this->app->user->admin and !$this->checkPriv($execution->id)) continue;
if($execution->status != 'done' and $execution->status != 'closed' and $execution->PM == $this->app->user->account)
{
$mineExecutions[$execution->id] = $execution;
@@ -2176,18 +2217,19 @@ class executionModel extends model
* @param int $queryID
* @param string $actionURL
* @param string $type
* @param int $objectID
* @param object $execution
* @access public
* @return void
*/
public function buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, $type = 'executionStory', $objectID = 0)
public function buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, $type = 'executionStory', $execution = null)
{
$this->app->loadLang('branch');
$branchPairs = array(BRANCH_MAIN => $this->lang->branch->main);
$productType = 'normal';
$productNum = count($products);
$productPairs = array(0 => '');
$branches = $this->loadModel('project')->getBranchesByProject($objectID);
$branches = $this->loadModel('project')->getBranchesByProject($execution->id);
foreach($products as $product)
{
$productPairs[$product->id] = $product->name;
@@ -2238,6 +2280,15 @@ class executionModel extends model
}
$this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $this->lang->story->statusList);
$project = $execution;
if(strpos('sprint,stage,kanban', $execution->type) !== false) $project = $this->loadModel('project')->getByID($execution->project);
if(isset($project->hasProduct) && empty($project->hasProduct))
{
unset($this->config->product->search['fields']['product']);
if($project->model != 'kanban') unset($this->config->product->search['fields']['plan']);
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
}
@@ -2328,28 +2379,14 @@ class executionModel extends model
*/
public function getTasks2Imported($toExecution, $branches)
{
if($this->config->systemMode == 'classic')
{
$products = $this->loadModel('product')->getProducts($toExecution);
if(empty($products)) return array();
$execution = $this->getById($toExecution);
$executions = $this->dao->select('t1.product, t1.project')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id')
->where('t1.product')->in(array_keys($products))
->andWhere('t2.project')->eq($execution->project)
->fetchGroup('project');
}
else
{
$execution = $this->getById($toExecution);
$project = $this->loadModel('project')->getById($execution->project);
$brotherProjects = $this->project->getBrotherProjects($project);
$executions = $this->dao->select('id')->from(TABLE_EXECUTION)
->where('project')->in($brotherProjects)
->andWhere('status')->ne('closed')
->fetchPairs('id');
}
$execution = $this->getById($toExecution);
$project = $this->loadModel('project')->getById($execution->project);
$brotherProjects = $this->project->getBrotherProjects($project);
$executions = $this->dao->select('id')->from(TABLE_EXECUTION)
->where('project')->in($brotherProjects)
->andWhere('multiple')->eq('1')
->andWhere('status')->ne('closed')
->fetchPairs('id');
$branches = str_replace(',', "','", $branches);
$tasks = $this->dao->select('t1.*, t2.id AS storyID, t2.title AS storyTitle, t2.version AS latestStoryVersion, t2.status AS storyStatus, t3.realname AS assignedToRealName')->from(TABLE_TASK)->alias('t1')
@@ -2425,15 +2462,19 @@ class executionModel extends model
/* Link stories. */
$executionStories = $this->loadModel('story')->getExecutionStoryPairs($executionID);
$lastOrder = (int)$this->dao->select('*')->from(TABLE_PROJECTSTORY)->where('project')->eq($executionID)->orderBy('order_desc')->limit(1)->fetch('order');
$lastOrder = (int)$this->dao->select('*')->from(TABLE_PROJECTSTORY)->where('project')->eq($executionID)->orderBy('order_desc')->limit(1)->fetch('order');
$stories = $this->dao->findById($storyID)->fields("id as story, product, version")->from(TABLE_STORY)->where('id')->in(array_keys($executionStories))->fetchAll('story');
foreach($stories as $storyID)
{
if(!isset($executionStories[$storyID]))
{
$story = $this->dao->findById($storyID)->fields("$executionID as project, id as story, product, version")->from(TABLE_STORY)->fetch();
$story->order = ++$lastOrder;
$story = zget($stories, $storyID, '');
if(empty($story)) continue;
$story->project = $executionID;
$story->order = ++$lastOrder;
$this->dao->insert(TABLE_PROJECTSTORY)->data($story)->exec();
$this->action->create('story', $storyID, 'linked2execution', '', $executionID);
if($execution->multiple or $execution->type == 'project') $this->action->create('story', $storyID, 'linked2execution', '', $executionID);
}
}
}
@@ -2767,7 +2808,7 @@ class executionModel extends model
$action = $execution->type == 'project' ? 'linked2project' : 'linked2execution';
if($action == 'linked2execution' and $execution->type == 'kanban') $action = 'linked2kanban';
$this->action->create('story', $storyID, $action, '', $executionID);
if($execution->multiple or $execution->type == 'project') $this->action->create('story', $storyID, $action, '', $executionID);
}
if(!isset($output['laneID']) or !isset($output['columnID'])) $this->kanban->updateLane($executionID, 'story');
@@ -2788,6 +2829,7 @@ class executionModel extends model
$linkedCases = $this->dao->select('*')->from(TABLE_PROJECTCASE)->where('project')->eq($executionID)->orderBy('order_desc')->fetchPairs('case', 'order');
$lastCaseOrder = empty($linkedCases) ? 0 : reset($linkedCases);
$cases = $this->dao->select('id, version')->from(TABLE_CASE)->where('story')->eq($storyID)->fetchPairs();
$execution = $this->getById($executionID);
foreach($cases as $caseID => $version)
{
if(isset($linkedCases[$caseID])) continue;
@@ -2801,9 +2843,8 @@ class executionModel extends model
$this->dao->insert(TABLE_PROJECTCASE)->data($object)->exec();
$action = $executionID == $this->session->project ? 'linked2project' : 'linked2execution';
$this->action->create('case', $caseID, $action, '', $executionID);
$action = $execution->type == 'project' ? 'linked2project' : 'linked2execution';
if($execution->multiple or $execution->type == 'project') $this->action->create('case', $caseID, $action, '', $executionID);
}
}
@@ -2849,12 +2890,10 @@ class executionModel extends model
}
}
if($this->config->systemMode == 'new')
{
$projectID = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch('project');
$this->session->set('project', $projectID);
$this->linkStory($projectID, $planStories, $planProducts);
}
$projectID = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch('project');
$this->session->set('project', $projectID);
$this->linkStory($projectID, $planStories, $planProducts);
$this->linkStory($executionID, $planStories, $planProducts);
}
@@ -2907,8 +2946,15 @@ class executionModel extends model
$this->loadModel('story')->setStage($storyID);
$this->unlinkCases($executionID, $storyID);
$objectType = $executionID == $this->session->project ? 'unlinkedfromproject' : 'unlinkedfromexecution';
$this->loadModel('action')->create('story', $storyID, $objectType, '', $executionID);
$objectType = $execution->type == 'project' ? 'unlinkedfromproject' : 'unlinkedfromexecution';
if($execution->multiple or $execution->type == 'project') $this->loadModel('action')->create('story', $storyID, $objectType, '', $executionID);
/* Sync unlink story in no multiple execution. */
if(empty($execution->multiple) and $execution->type != 'project')
{
$this->dao->delete()->from(TABLE_PROJECTSTORY)->where('project')->eq($execution->project)->andWhere('story')->eq($storyID)->limit(1)->exec();
$this->loadModel('action')->create('story', $storyID, 'unlinkedfromproject', '', $execution->project);
}
$tasks = $this->dao->select('id')->from(TABLE_TASK)->where('story')->eq($storyID)->andWhere('execution')->eq($executionID)->andWhere('status')->in('wait,doing')->fetchPairs('id');
foreach($tasks as $taskID)
@@ -2931,12 +2977,20 @@ class executionModel extends model
public function unlinkCases($executionID, $storyID)
{
$this->loadModel('action');
$cases = $this->dao->select('id')->from(TABLE_CASE)->where('story')->eq($storyID)->fetchAll('id');
$execution = $this->dao->findById($executionID)->from(TABLE_EXECUTION)->fetch();
$cases = $this->dao->select('id')->from(TABLE_CASE)->where('story')->eq($storyID)->fetchAll('id');
foreach($cases as $caseID => $case)
{
$this->dao->delete()->from(TABLE_PROJECTCASE)->where('project')->eq($executionID)->andWhere('`case`')->eq($caseID)->limit(1)->exec();
$action = $executionID == $this->session->project ? 'unlinkedfromproject' : 'unlinkedfromexecution';
$this->action->create('case', $caseID, $action, '', $executionID);
$action = $execution->type == 'project' ? 'unlinkedfromproject' : 'unlinkedfromexecution';
if($execution->multiple or $execution->type == 'project') $this->action->create('case', $caseID, $action, '', $executionID);
/* Sync unlink case in no multiple execution. */
if(empty($execution->multiple) and $execution->type != 'project')
{
$this->dao->delete()->from(TABLE_PROJECTCASE)->where('project')->eq($execution->project)->andWhere('`case`')->eq($caseID)->limit(1)->exec();
$this->loadModel('action')->create('case', $caseID, 'unlinkedfromproject', '', $execution->project);
}
}
$order = 1;
@@ -3038,7 +3092,7 @@ class executionModel extends model
*/
public function getCanCopyObjects($projectID = 0)
{
if(empty($projectID) and $this->config->systemMode == 'new') return array();
if(empty($projectID)) return array();
$objectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)
->where('deleted')->eq(0)
@@ -4330,6 +4384,7 @@ class executionModel extends model
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->where('t1.project')->eq((int)$executionID)
->andWhere('t2.deleted')->eq(0)
->andWhere('t2.type')->eq('story')
->orderBy('t1.`order`_desc')
->fetchAll();
}
@@ -4553,10 +4608,11 @@ class executionModel extends model
* Print html for tree.
*
* @param object $trees
* @param bool $hasProduct true|false
* @access pubic
* @return string
*/
public function printTree($trees)
public function printTree($trees, $hasProduct = true)
{
$html = '';
foreach($trees as $tree)
@@ -4576,8 +4632,9 @@ class executionModel extends model
break;
case 'product':
$this->app->loadLang('product');
$productName = $hasProduct ? $this->lang->productCommon : $this->lang->projectCommon;
$html .= '<li class="item-product">';
$html .= '<a class="tree-toggle"><span class="label label-type">' . $this->lang->productCommon . "</span><span class='title' title='{$tree->name}'>" . $tree->name . '</span></a>';
$html .= '<a class="tree-toggle"><span class="label label-type">' . $productName . "</span><span class='title' title='{$tree->name}'>" . $tree->name . '</span></a>';
break;
case 'story':
$this->app->loadLang('story');
@@ -4594,7 +4651,7 @@ class executionModel extends model
if(isset($tree->children))
{
$html .= '<ul>';
$html .= $this->printTree($tree->children);
$html .= $this->printTree($tree->children, $hasProduct);
$html .= '</ul>';
}
$html .= '</li>';
@@ -4636,11 +4693,8 @@ class executionModel extends model
echo "<tr $trAttrs class='$trClass'>";
echo "<td class='c-name text-left flex sort-handler'>";
if(common::hasPriv('execution', 'batchEdit')) echo "<span id=$execution->id class='table-nest-icon icon table-nest-toggle'></span>";
if($this->config->systemMode == 'new')
{
$spanClass = $execution->type == 'stage' ? 'label-warning' : 'label-info';
echo "<span class='project-type-label label label-outline $spanClass'>{$this->lang->execution->typeList[$execution->type]}</span> ";
}
$spanClass = $execution->type == 'stage' ? 'label-warning' : 'label-info';
echo "<span class='project-type-label label label-outline $spanClass'>{$this->lang->execution->typeList[$execution->type]}</span> ";
if(empty($execution->children))
{
echo html::a(helper::createLink('execution', 'view', "executionID=$execution->id"), $execution->name, '', 'class="text-ellipsis"');
@@ -4783,16 +4837,16 @@ class executionModel extends model
}
/**
** Set stage tree path.
**
** @param int $executionID
** @access public
** @return bool
**/
* Set stage tree path.
*
* @param int $executionID
* @access public
* @return bool
*/
public function setTreePath($executionID)
{
$execution = $this->dao->select('id,type,parent,path,grade')->from(TABLE_PROJECT)->where('id')->eq($executionID)->fetch();
$parent = $this->dao->select('id,type,parent,path,grade')->from(TABLE_PROJECT)->where('id')->eq($execution->parent)->fetch();
$execution = $this->dao->select('id, type, parent, path, grade')->from(TABLE_PROJECT)->where('id')->eq($executionID)->fetch();
$parent = $this->dao->select('id, type, parent, path, grade')->from(TABLE_PROJECT)->where('id')->eq($execution->parent)->fetch();
if($parent->type == 'project')
{
@@ -4859,7 +4913,7 @@ class executionModel extends model
$onlyChildStage = ($execution->grade == 2 and $execution->project != $execution->parent);
if(!$isStage and in_array($col->id, array('percent', 'attribute', 'actions'))) return;
if(($this->config->systemMode == 'classic' or ($this->config->systemMode == 'new' and $this->app->tab != 'execution')) and $col->id == 'project') return;
if($this->app->tab != 'execution' and $col->id == 'project') return;
if($col->show)
{
@@ -4924,7 +4978,7 @@ class executionModel extends model
case 'name':
$label = $execution->type == 'stage' ? 'label-warning' : 'label-info';
$executionLink = $execution->projectModel == 'kanban' ? html::a(helper::createLink('execution', 'kanban', 'executionID=' . $execution->id), $execution->name, '', "class='text-ellipsis'") : html::a(helper::createLink('execution', 'task', 'execution=' . $execution->id), $execution->name, '', "class='text-ellipsis'");
if($this->config->systemMode != 'classic' and !$onlyChildStage) echo "<span class='project-type-label label label-outline $label'>{$this->lang->execution->typeList[$execution->type]}</span>";
if(!$onlyChildStage) echo "<span class='project-type-label label label-outline $label'>{$this->lang->execution->typeList[$execution->type]}</span>";
if($onlyChildStage) echo "<span class='label label-badge label-light label-children'>{$this->lang->programplan->childrenAB}</span> ";
echo !empty($execution->children) ? "<span class='text-ellipsis'>$execution->name</span>" : $executionLink;
if(isset($execution->delay)) echo "<span class='label label-danger label-badge'>{$this->lang->execution->delayed}</span> ";
@@ -5033,4 +5087,105 @@ class executionModel extends model
$this->loadModel('search')->setSearchParams($this->config->execution->all->search);
}
/*
* Create default sprint.
*
* @param int $projectID
* @return int
* */
public function createDefaultSprint($projectID)
{
$project = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch();
$post = $_POST;
$_POST = array();
$_POST['project'] = $projectID;
$_POST['name'] = $project->name;
$_POST['code'] = $project->code;
$_POST['begin'] = $project->begin;
$_POST['end'] = $project->end;
$_POST['status'] = 'wait';
$_POST['days'] = $project->days;
$_POST['team'] = $project->team;
$_POST['teamMembers'] = array($this->app->user->account);
$_POST['acl'] = 'open';
$_POST['PO'] = '';
$_POST['QD'] = '';
$_POST['PM'] = '';
$_POST['RD'] = '';
$_POST['multiple'] = '0';
$_POST['hasProduct'] = $project->hasProduct;
$projectProducts = $this->dao->select('*')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchAll();
foreach($projectProducts as $projectProduct)
{
$_POST['products'][] = $projectProduct->product;
$_POST['branch'][] = $projectProduct->branch;
if($projectProduct->plan) $_POST['plans'][$projectProduct->product][$projectProduct->branch] = explode(',', trim($projectProduct->plan, ','));
}
$executionID = $this->create();
if($project->model == 'kanban')
{
$execution = $this->getById($executionID);
$this->loadModel('kanban')->createRDKanban($execution);
}
$_POST = $post;
return $executionID;
}
/**
* Sync no multiple project to sprint.
*
* @param int $projectID
* @access public
* @return int
*/
public function syncNoMultipleSprint($projectID)
{
$project = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch();
$post = $_POST;
$_POST = array();
$_POST['project'] = $projectID;
$_POST['name'] = $project->name;
$_POST['code'] = $project->code;
$_POST['begin'] = $project->begin;
$_POST['end'] = $project->end;
$_POST['realBegan'] = $project->realBegan;
$_POST['realEnd'] = $project->realEnd;
$_POST['days'] = $project->days;
$_POST['team'] = $project->team;
$_POST['PO'] = $project->PO;
$_POST['QD'] = $project->QD;
$_POST['PM'] = $project->PM;
$_POST['RD'] = $project->RD;
$_POST['status'] = $project->status;
$_POST['acl'] = 'open';
$projectProducts = $this->dao->select('*')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchAll();
foreach($projectProducts as $projectProduct)
{
$_POST['products'][] = $projectProduct->product;
$_POST['branch'][] = $projectProduct->branch;
if($projectProduct->plan) $_POST['plans'][$projectProduct->product][$projectProduct->branch] = explode(',', trim($projectProduct->plan, ','));
}
$teamMembers = $this->dao->select('*')->from(TABLE_TEAM)->where('type')->eq('project')->andWhere('root')->eq($projectID)->fetchPairs('account', 'account');
$_POST['teamMembers'] = array_values($teamMembers);
$executionID = $this->dao->select('*')->from(TABLE_EXECUTION)->where('project')->eq($projectID)->andWhere('type')->in('sprint,kanban')->andWhere('multiple')->eq(0)->fetch('id');
if($executionID)
{
$this->update($executionID);
$this->updateProducts($executionID);
}
$_POST = $post;
return $executionID;
}
}
+13 -6
View File
@@ -31,6 +31,7 @@
<?php
$executionCounts = array();
$executionNames = array();
$currentExecution = '';
$tabActive = '';
$myExecutions = 0;
$others = 0;
@@ -57,16 +58,16 @@ foreach($executions as $projectID => $projectExecutions)
}
$executionsPinYin = common::convert2Pinyin($executionNames);
$myExecutionsHtml = $config->systemMode == 'new' ? '<ul class="tree tree-angles" data-ride="tree">' : '<ul class="noProject">';
$normalExecutionsHtml = $config->systemMode == 'new' ? '<ul class="tree tree-angles" data-ride="tree">' : '<ul class="noProject">';
$closedExecutionsHtml = $config->systemMode == 'new' ? '<ul class="tree tree-angles" data-ride="tree">' : '<ul class="noProject">';
$myExecutionsHtml = '<ul class="tree tree-angles" data-ride="tree">';
$normalExecutionsHtml = '<ul class="tree tree-angles" data-ride="tree">';
$closedExecutionsHtml = '<ul class="tree tree-angles" data-ride="tree">';
$kanbanLink = $this->createLink('execution', 'kanban', "executionID=%s");
$taskLink = $this->createLink('execution', 'task', "executionID=%s");
foreach($executions as $projectID => $projectExecutions)
{
/* Adapt to the old version. */
if($projectID and $config->systemMode == 'new')
if($projectID)
{
$projectName = zget($projects, $projectID);
@@ -82,11 +83,13 @@ foreach($executions as $projectID => $projectExecutions)
if(isset($execution->type) and $execution->type == 'kanban' and !$isKanbanMethod) $executionLink = $kanbanLink;
if(isset($execution->type) and $execution->type != 'kanban' and strpos(',kanban,cfd,', ",$method,") !== false) $executionLink = $taskLink;
if($execution->id == $executionID) $currentExecution = $execution;
$selected = $execution->id == $executionID ? 'selected' : '';
if(!empty($execution->children))
{
foreach($execution->children as $id)
{
if($execution->id == $executionID) $currentExecution = $execution;
$selected = $id == $executionID ? 'selected' : '';
if($execution->status != 'done' and $execution->status != 'closed' and ($execution->PM == $this->app->user->account or isset($execution->teams[$this->app->user->account])))
{
@@ -112,7 +115,7 @@ foreach($executions as $projectID => $projectExecutions)
}
}
}
else if($execution->grade == 1 or $config->systemMode == 'classic')
else if($execution->grade == 1)
{
if($execution->status != 'done' and $execution->status != 'closed' and ($execution->PM == $this->app->user->account or isset($execution->teams[$this->app->user->account])))
{
@@ -180,10 +183,14 @@ $closedExecutionsHtml .= '</ul>';
<div class='list-group executions'><?php echo $closedExecutionsHtml;?></div>
</div>
</div>
<script>scrollToSelected();</script>
<script>
$(function()
{
<?php if($currentExecution->status == 'done' or $currentExecution->status == 'closed'):?>
$('.col-footer .toggle-right-col').click(function(){ scrollToSelected(); })
<?php else:?>
scrollToSelected();
<?php endif;?>
$('.nav-tabs li span').hide();
$('.nav-tabs li.active').find('span').show();
+2 -4
View File
@@ -65,7 +65,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
</div>
<div class='btn-toolbar pull-right'>
<?php common::printLink('execution', 'export', "status=$status&productID=$productID&orderBy=$orderBy&from=$from", "<i class='icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link export'")?>
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create'), "<i class='icon icon-sm icon-plus'></i> " . ((($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-primary create-execution-btn' data-app='execution' onclick='$(this).removeAttr(\"data-toggle\")'");?>
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create'), "<i class='icon icon-sm icon-plus'></i> " . ($from == 'execution' ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-primary create-execution-btn' data-app='execution' onclick='$(this).removeAttr(\"data-toggle\")'");?>
</div>
</div>
<div id='mainContent' class="main-row fade">
@@ -76,7 +76,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
<span class="text-muted"><?php echo $from == 'execution' ? $lang->execution->noExecutions : $lang->execution->noExecution;?></span>
<?php if(empty($allExecutionsNum)):?>
<?php if(common::hasPriv('execution', 'create')):?>
<?php echo html::a($this->createLink('execution', 'create'), "<i class='icon icon-plus'></i> " . (($from == 'execution' and $config->systemMode == 'new') ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-info' data-app='execution'");?>
<?php echo html::a($this->createLink('execution', 'create'), "<i class='icon icon-plus'></i> " . ($from == 'execution' ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-info' data-app='execution'");?>
<?php endif;?>
<?php endif;?>
</p>
@@ -104,8 +104,6 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
{
if($value->show)
{
if($config->systemMode == 'classic' and $value->id == 'project') continue;
$this->datatable->printHead($value, $orderBy, $vars, $canBatchEdit);
$columns ++;
}
+2 -2
View File
@@ -48,7 +48,7 @@
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB;?></th>
<?php if($config->systemMode == 'new' and isset($project) and $project->model == 'scrum'):?>
<?php if(isset($project) and $project->model == 'scrum'):?>
<th class='c-project required <?php echo $minWidth?>' style="width:100%"><?php echo $lang->execution->projectName;?></th>
<?php endif;?>
<th class='required <?php echo $minWidth?>' style="width:100%"><?php echo $lang->execution->$name;?></th>
@@ -82,7 +82,7 @@
?>
<tr>
<td><?php echo sprintf('%03d', $executionID) . html::hidden("executionIDList[$executionID]", $executionID);?></td>
<?php if($config->systemMode == 'new' and isset($project) and $project->model == 'scrum'):?>
<?php if(isset($project) and $project->model == 'scrum'):?>
<td class='text-left' style='overflow:visible'><?php echo html::select("projects[$executionID]", $allProjects, $executions[$executionID]->project, "class='form-control picker-select' data-lastselected='{$executions[$executionID]->project}' onchange='changeProject(this, $executionID, {$executions[$executionID]->project})'");?></td>
<?php endif;?>
<td title='<?php echo $executions[$executionID]->name?>'><?php echo html::input("names[$executionID]", $executions[$executionID]->name, "class='form-control'");?></td>
+7 -1
View File
@@ -124,6 +124,7 @@
<?php
foreach($setting as $value)
{
if(!$project->hasProduct and $project->model != 'scrum' and $value->id == 'plan') continue;
if($value->show)
{
if(common::checkNotCN() and $value->id == 'severity') $value->name = $lang->bug->severity;
@@ -150,7 +151,12 @@
}
}?>
<?php else:?>
<?php foreach($setting as $value) $this->bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, $executions, $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table', $projectPairs);?>
<?php foreach($setting as $value)
{
if(!$project->hasProduct and $project->model != 'scrum' and $value->id == 'plan') continue;
$this->bug->printCell($value, $bug, $users, $builds, $branchOption, $modulePairs, $executions, $plans, $stories, $tasks, $useDatatable ? 'datatable' : 'table', $projectPairs);
}
?>
<?php endif;?>
</tr>
<?php endforeach;?>
+3 -1
View File
@@ -25,7 +25,7 @@
echo html::a(inlink('build', "executionID=$executionID&type=$featureType"), $label, '',"class='btn btn-link $activeClass' data-app={$app->tab} id='$featureType'");
}
?>
<div class="input-control space w-150px"><?php echo html::select('product', $products, $product, "onchange='changeProduct(this.value)' class='form-control chosen' data-placeholder='{$lang->productCommon}'");?></div>
<div class="input-control space w-150px <?php echo $hidden;?>"><?php echo html::select('product', $products, $product, "onchange='changeProduct(this.value)' class='form-control chosen' data-placeholder='{$lang->productCommon}'");?></div>
</div>
<a class="btn btn-link querybox-toggle" id="bysearchTab"><i class="icon icon-search muted"></i> <?php echo $lang->execution->byQuery;?></a>
<div class="btn-toolbar pull-right">
@@ -49,6 +49,7 @@
<thead>
<tr>
<th class="c-id-sm"><?php echo $lang->build->id;?></th>
<th class="c-name w-200px text-left <?php echo $hidden;?>"><?php echo $lang->build->product;?></th>
<th class="c-name text-left"><?php echo $lang->build->name;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->product;?></th>
<th class="c-url"><?php echo $lang->build->scmPath;?></th>
@@ -63,6 +64,7 @@
<?php foreach($builds as $index => $build):?>
<tr data-id="<?php echo $productID;?>">
<td class="c-id-sm text-muted"><?php echo html::a(helper::createLink('build', 'view', "buildID=$build->id"), sprintf('%03d', $build->id));?></td>
<td class="c-name text-left <?php echo $hidden;?>" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<td class="c-name">
<?php if($build->branchName) echo "<span class='label label-outline label-badge'>{$build->branchName}</span>"?>
<?php echo html::a($this->createLink('build', 'view', "build=$build->id"), $build->name);?>
-2
View File
@@ -36,11 +36,9 @@
if(common::canModify('execution', $execution)) common::printLink('execution', 'fixFirst', "execution=$execution->id", $lang->execution->fixFirst, '', "class='btn btn-link iframe' data-width='700'");
echo $lang->execution->howToUpdateBurn;
?>
<?php if($config->systemMode == 'new'):?>
<div class='input-control w-150px'>
<?php echo html::select('burnBy', $lang->execution->burnByList, $burnBy, "class='form-control chosen'");?>
</div>
<?php endif;?>
<?php if($interval):?>
<div class='input-control thWidth'>
<?php echo html::select('interval', $dayList, $interval, "class='form-control chosen'");?>
+8 -12
View File
@@ -10,13 +10,12 @@
* @link http://www.zentao.net
*/
?>
<?php $showExecutionExec = !empty($from) and ($from == 'execution' || $from == 'doc') and ($config->systemMode == 'new');?>
<?php $showExecutionExec = !empty($from) and ($from == 'execution' || $from == 'doc');?>
<?php if(isset($tips)):?>
<?php $defaultURL = $this->createLink('execution', 'task', "execution=$executionID");?>
<?php include '../../common/view/header.html.php';?>
<body>
<?php $tipsModal = $this->config->systemMode == 'new' ? 'newTipsModal' : 'classicTipsModal';?>
<div class='modal-dialog' id='<?php echo $tipsModal;?>'>
<div class='modal-dialog' id='newTipsModal'>
<div class='modal-header'>
<a href='<?php echo $defaultURL;?>' class='close'><i class="icon icon-close"></i></a>
<h4 class='modal-title' id='myModalLabel'><?php echo $lang->execution->tips;?></h4>
@@ -40,10 +39,8 @@
<?php js::set('productID', empty($productID) ? 0 : $productID);?>
<?php js::set('isStage', $isStage);?>
<?php js::set('copyExecutionID', $copyExecutionID);?>
<?php js::set('systemMode', $config->systemMode);?>
<?php js::set('projectCommon', $lang->project->common);?>
<?php js::set('multiBranchProducts', $multiBranchProducts);?>
<?php js::set('systemMode', $config->systemMode);?>
<?php js::set('projectID', $projectID);?>
<?php js::set('copyExecutionID', $copyExecutionID);?>
<?php js::set('cancelCopy', $lang->execution->cancelCopy);?>
@@ -58,13 +55,11 @@
</div>
<form class='form-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<?php if($config->systemMode == 'new'):?>
<tr>
<th class='w-120px'><?php echo $lang->execution->projectName;?></th>
<td class="col-main"><?php echo html::select("project", $allProjects, $projectID, "class='form-control chosen' required onchange='refreshPage(this.value)'");?></td>
<td colspan='2'></td>
</tr>
<?php endif;?>
<tr>
<th class='w-120px'><?php echo $showExecutionExec ? $lang->execution->execName : $lang->execution->name;?></th>
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
@@ -132,7 +127,9 @@
<td></td>
</tr>
<?php $this->printExtendFields('', 'table', 'columns=3');?>
<tr>
<?php $hidden = 'hide'?>
<?php if(!empty($project->hasProduct)) $hidden = ''?>
<tr class="<?php echo $hidden;?>">
<th><?php echo $lang->execution->manageProducts;?></th>
<td class='text-left' id='productsBox' colspan="3">
<div class='row'>
@@ -159,7 +156,8 @@
</div>
</td>
</tr>
<tr>
<?php if(isset($project->model) and $project->model == 'scrum') $hidden = '';?>
<tr class="<?php echo $hidden?>">
<th><?php echo $lang->execution->linkPlan;?></th>
<td colspan="3" id="plansBox">
<div class='row'>
@@ -259,9 +257,7 @@
<div class='modal-header'>
<button type='button' class='close' data-dismiss='modal'><i class="icon icon-close"></i></button>
<div class='titleBox'><h4 class='modal-title' id='myModalLabel'><?php echo $lang->execution->copyTitle;?></h4></div>
<?php if($this->config->systemMode == 'new'):?>
<div class='projectSelect'><?php echo html::select("project", $copyProjects, $projectID, "class='form-control chosen' required onchange='loadProjectExecutions(this.value)'");?></div>
<?php endif;?>
</div>
<div class='modal-body'>
<?php if(count($executions) == 1):?>
@@ -271,7 +267,7 @@
</div>
<?php else:?>
<div id='copyProjects' class='row'>
<?php if($config->systemMode == 'new' and $projectID == 0) $executions = $copyExecutions;?>
<?php if($projectID == 0) $executions = $copyExecutions;?>
<?php foreach ($executions as $id => $execution):?>
<?php if(empty($id)):?>
<?php if($copyExecutionID != 0):?>
+12 -15
View File
@@ -23,10 +23,10 @@
<small><?php echo $lang->arrow . ' ' . $lang->execution->edit;?></small>
</h2>
</div>
<?php if($config->systemMode == 'new') echo html::hidden('project', $project->id);?>
<?php echo html::hidden('project', $project->id);?>
<form class='load-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<?php if($config->systemMode == 'new' and isset($project)):?>
<?php if(isset($project)):?>
<?php if($project->model == 'scrum'):?>
<tr>
<th class='w-120px'><?php echo $lang->execution->projectName;?></th>
@@ -139,7 +139,9 @@
</tr>
<?php endif;?>
<?php if(!in_array($execution->attribute, array('request', 'design', 'review'))): ?>
<tr>
<?php $hidden = 'hide'?>
<?php if(!empty($project->hasProduct)) $hidden = ''?>
<tr class="<?php echo $hidden;?>">
<th><?php echo $lang->execution->manageProducts;?></th>
<td class='text-left' id='productsBox' colspan="2">
<?php $class = $execution->grade == 2 ? "readonly='readonly'" : '';?>
@@ -150,19 +152,12 @@
<?php foreach($linkedBranches[$product->id] as $branchID => $branch):?>
<div class='col-sm-4'>
<div class="input-group<?php if($hasBranch) echo ' has-branch';?>">
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' $class onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='". $product->type ."'");?>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' $class onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='". $product->type ."' data-lastBranch='" . $branchID . "'");?>
<span class='input-group-addon fix-border'></span>
<?php if($hasBranch) echo html::select("branch[$i]", $branchGroups[$product->id], $branchID, "class='form-control chosen' $class onchange=\"loadPlans('#products{$i}', this.value)\" data-last='" . $branchID . "'");?>
</div>
</div>
<?php
if(in_array($product->id, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches))
{
echo html::hidden("products[$i]", $product->id);
echo html::hidden("branch[$i]", $branchID);
}
$i++;
?>
<?php $i++; ?>
<?php endforeach;?>
<?php endforeach;?>
<div class='col-sm-4'>
@@ -174,7 +169,8 @@
</div>
</td>
</tr>
<tr>
<?php if(isset($project->model) and $project->model == 'scrum') $hidden = '';?>
<tr class="<?php echo $hidden?>">
<th><?php echo $lang->execution->linkPlan;?></th>
<td id="plansBox" colspan="2">
<div class='row'>
@@ -231,7 +227,8 @@
<?php js::set('unmodifiableBranches', $unmodifiableBranches)?>
<?php js::set('linkedStoryIDList', $linkedStoryIDList)?>
<?php js::set('multiBranchProducts', $multiBranchProducts);?>
<?php js::set('tip', $lang->execution->notAllowRemoveProducts);?>
<?php js::set('confirmSync', $lang->execution->confirmSync);?>
<?php js::set('systemMode', $config->systemMode);?>
<?php js::set('allProducts', $allProducts);?>
<?php js::set('branchGroups', $branchGroups);?>
<?php js::set('unLinkProductTip', $lang->project->unLinkProductTip);?>
<?php include '../../common/view/footer.html.php';?>
+9 -7
View File
@@ -61,21 +61,21 @@ js::set('rdSearchValue', '');
js::set('defaultMinColWidth', $this->config->minColWidth);
js::set('defaultMaxColWidth', $this->config->maxColWidth);
$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1;
$canSortRegion = (commonModel::hasPriv('kanban', 'sortRegion') and count($regions) > 1);
$canCreateRegion = (common::hasPriv('kanban', 'createRegion') and $groupBy == 'default');
$canEditRegion = commonModel::hasPriv('kanban', 'editRegion');
$canDeleteRegion = commonModel::hasPriv('kanban', 'deleteRegion');
$canCreateLane = commonModel::hasPriv('kanban', 'createLane');
$canCreateTask = common::hasPriv('task', 'create');
$canBatchCreateTask = common::hasPriv('task', 'batchCreate');
$canImportTask = common::hasPriv('execution', 'importTask');
$canImportTask = (common::hasPriv('execution', 'importTask') and $execution->multiple);
$canCreateBug = ($productID and common::hasPriv('bug', 'create'));
$canBatchCreateBug = ($productID and common::hasPriv('bug', 'batchCreate'));
$canBatchCreateBug = ($productID and common::hasPriv('bug', 'batchCreate') and $execution->multiple);
$canImportBug = ($productID and common::hasPriv('execution', 'importBug'));
$canCreateStory = ($productID and common::hasPriv('story', 'create'));
$canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate'));
$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory'));
$canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories'));
$canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories') and !empty($project->hasProduct));
$hasStoryButton = ($canCreateStory or $canBatchCreateStory or $canLinkStory or $canLinkStoryByPlan);
$hasTaskButton = ($canCreateTask or $canBatchCreateTask or $canImportBug);
$hasBugButton = ($canCreateBug or $canBatchCreateBug);
@@ -118,7 +118,7 @@ js::set('priv',
'canDeleteStory' => common::hasPriv('story', 'delete'),
'canChangeStory' => common::hasPriv('story', 'change'),
'canCloseStory' => common::hasPriv('story', 'close'),
'canUnlinkStory' => common::hasPriv('execution', 'unlinkStory'),
'canUnlinkStory' => (common::hasPriv('execution', 'unlinkStory') and !empty($execution->hasProduct)),
'canViewStory' => common::hasPriv('execution', 'storyView'),
)
);
@@ -161,11 +161,13 @@ js::set('priv',
echo html::a('javascript:toggleRDSearchBox()', "<i class='icon-search muted'></i> " . $lang->searchAB, '', "class='btn btn-link querybox-toggle'");
echo html::a('javascript:fullScreen()', "<i class='icon-fullscreen muted'></i> " . $lang->kanban->fullScreen, '', "class='btn btn-link'");
if(common::hasPriv('execution', 'setKanban')) echo html::a(helper::createLink('execution', 'setKanban', "executionID=$execution->id", '', true), '<i class="icon icon-cog-outline"></i> ' . $lang->settings, '', "class='iframe btn btn-link text-left' data-width='$width'");
if(common::hasPriv('execution', 'edit')) echo html::a(helper::createLink('execution', 'edit', "executionID=$execution->id", '', true), '<i class="icon icon-edit"></i> ' . $lang->edit, '', "class='iframe btn btn-link text-left' data-width='80%'");
if(!$execution->multiple and common::hasPriv('project', 'edit')) $editURL = helper::createLink('project', 'edit', "projectID=$execution->project", '', true);
if($execution->multiple and common::hasPriv('execution', 'edit')) $editURL = helper::createLink('execution', 'edit', "executionID=$execution->id", '', true);
if(!empty($editURL)) echo html::a($editURL, '<i class="icon icon-edit"></i> ' . $lang->edit, '', "class='iframe btn btn-link text-left' data-width='80%'");
$actions = '';
$printSettingBtn = (common::hasPriv('execution', 'close') or common::hasPriv('execution', 'delete') or !empty($executionActions));
if($printSettingBtn)
if($printSettingBtn and $execution->multiple)
{
$actions .= "<div class='btn-group menu-actions'>";
$actions .= html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
+8 -4
View File
@@ -43,11 +43,13 @@
</th>
<th class='c-pri' title=<?php echo $lang->execution->pri;?>><?php echo $lang->priAB;?></th>
<th><?php echo $lang->story->title;?></th>
<?php if($project->hasProduct):?>
<th class='c-object'><?php echo $lang->story->product;?></th>
<?php endif;?>
<th class='c-module'><?php echo $lang->story->module;?></th>
<th class='c-plan'><?php echo $lang->story->plan;?></th>
<th class='c-plan <?php if(empty($project->hasProduct) && $project->model != 'scrum') echo 'hide';?>'><?php echo $lang->story->plan;?></th>
<th class='c-stage'><?php echo $lang->story->stage;?></th>
<?php if($productType != 'normal'):?>
<?php if($project->hasProduct && $productType != 'normal'):?>
<th class='c-branch'><?php echo $lang->product->branchName[$productType];?></th>
<?php endif;?>
<th class='c-user'><?php echo $lang->openedByAB;?></th>
@@ -77,11 +79,13 @@
}
?>
</td>
<?php if($project->hasProduct):?>
<td class='text-left' title='<?php echo $products[$story->product]->name?>'><?php echo html::a($this->createLink('product', 'browse', "productID=$story->product&branch=$story->branch"), $products[$story->product]->name);?></td>
<?php endif;?>
<td class='c-module text-left' title='<?php echo zget($modules, $story->module, '')?>'><?php echo zget($modules, $story->module, '')?></td>
<td class='text-ellipsis' title='<?php echo $story->planTitle;?>'><?php echo $story->planTitle;?></td>
<td class='text-ellipsis <?php if(empty($project->hasProduct) && $project->model != 'scrum') echo 'hide';?>' title='<?php echo $story->planTitle;?>'><?php echo $story->planTitle;?></td>
<td><?php echo zget($lang->story->stageList, $story->stage);?></td>
<?php if($productType != 'normal'):?>
<?php if($project->hasProduct && $productType != 'normal'):?>
<td><?php if(isset($branchGroups[$story->product][$story->branch])) echo $branchGroups[$story->product][$story->branch];?></td>
<?php endif;?>
<td class='c-user'><?php echo zget($users, $story->openedBy);?></td>
@@ -11,7 +11,6 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('systemMode', $config->systemMode);?>
<?php js::set('projectCommon', $lang->project->common);?>
<?php js::set('executionID', $execution->id);?>
<?php js::set('team2Import', $team2Import);?>
+10 -12
View File
@@ -11,7 +11,12 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('systemMode', $config->systemMode);?>
<?php js::set('unmodifiableProducts',$unmodifiableProducts);?>
<?php js::set('unmodifiableBranches', $unmodifiableBranches);?>
<?php js::set('linkedStoryIDList', $linkedStoryIDList);?>
<?php js::set('allProducts', $allProducts);?>
<?php js::set('branchGroups', $branchGroups);?>
<?php js::set('unLinkProductTip', $lang->project->unLinkProductTip);?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<span class='btn btn-link btn-active-text'><span class='text'><?php echo $lang->execution->manageProducts;?></span></span>
@@ -24,25 +29,18 @@
<div class='detail-title'><?php echo $lang->execution->linkedProducts;?></div>
<div class='detail-content row'>
<?php $i = 0;?>
<?php $attr = '';?>
<?php foreach($allProducts as $productID => $productName):?>
<?php if(isset($linkedProducts[$productID])):?>
<?php foreach($linkedBranches[$productID] as $branchID):?>
<?php if((in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches)) and !empty($linkedStoryIDList[$productID][$branchID])) $attr = "disabled='disabled'";?>
<?php if((!(in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches)) or empty($linkedStoryIDList[$productID][$branchID]))) $attr = '';?>
<?php if($execution->grade == '2' and ($linkedProducts[$productID]->type == 'normal' or $branchID == 0)) $attr = "disabled='disabled'";?>
<?php $title = (in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches) and !empty($linkedStoryIDList[$productID][$branchID])) ? sprintf($lang->execution->notAllowRemoveProducts, $linkedStoryIDList[$productID][$branchID]) : $productName;?>
<?php $checked = 'checked';?>
<div class='col-sm-4'>
<div class='product <?php echo $checked . (isset($allBranches[$productID]) ? ' has-branch' : '')?>'>
<div class="checkbox-primary" title='<?php echo $title;?>'>
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' $checked $attr id='products{$productID}'>";?>
<div class='product checked <?php echo (isset($allBranches[$productID]) ? ' has-branch' : '')?>'>
<div class="checkbox-primary" title='<?php echo $productName;?>'>
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' checked id='products{$productID}'>";?>
<label class='text-ellipsis checkbox-inline' for='<?php echo 'products' . $productID;?>' title='<?php echo $productName;?>'><?php echo $productName;?></label>
</div>
<?php if(isset($allBranches[$productID][$branchID])) echo html::select("branch[$i]", $allBranches[$productID], $branchID, "class='form-control picker-select' disabled='disabled'");?>
</div>
</div>
<?php if(!empty($attr)) echo html::hidden("products[$i]", $productID);?>
<?php echo html::hidden("branch[$i]", $branchID);?>
<?php if(!isset($branchGroups[$productID])) unset($allProducts[$productID]);?>
<?php if(isset($branchGroups[$productID][$branchID])) unset($branchGroups[$productID][$branchID]);?>
@@ -53,7 +51,7 @@
<?php endforeach;?>
</div>
</div>
<?php if($this->config->systemMode == 'classic' or $execution->grade == 1):?>
<?php if($execution->grade == 1):?>
<div class='detail'>
<div class='detail-title'><?php echo $lang->execution->unlinkedProducts;?></div>
<div class='detail-content row'>
+77 -19
View File
@@ -19,6 +19,8 @@
<?php js::set('branchID', str_replace(',', '_', $this->cookie->storyBranchParam));?>
<?php js::set('executionID', $execution->id);?>
<?php js::set('projectID', $execution->project);?>
<?php js::set('storyType', $storyType);?>
<?php js::set('isDropMenu', (!$execution->hasProduct and !$execution->multiple and $config->URAndSR));?>
<?php js::set('confirmUnlinkStory', $lang->execution->confirmUnlinkStory)?>
<?php js::set('typeError', sprintf($this->lang->error->notempty, $this->lang->task->type))?>
<?php js::set('typeNotEmpty', sprintf($this->lang->error->notempty, $this->lang->task->type));?>
@@ -33,6 +35,13 @@
.btn-group button.dropdown-toggle.btn-secondary, .btn-group button.dropdown-toggle.btn-primary {padding:6px;}
.export {margin-left: 0px !important;}
</style>
<?php if(!$execution->hasProduct && $execution->type != 'sprint'):?>
<style>
#executionStoryForm th.c-plan {display: none !important;}
#executionStoryForm td.c-plan {display: none !important;}
#customDatatable div.col[data-key=plan] {display: none !important;}
</style>
<?php endif;?>
<?php $isAllModules = (!empty($module->name) or !empty($product->name) or !empty($branch)) ? false : true;?>
<?php $sidebarName = $lang->tree->all;?>
<?php $removeBtn = '';?>
@@ -43,7 +52,7 @@
{
$sidebarName = isset($product) ? $product->name : (isset($branch) ? $branch : $module->name);
$removeType = isset($product) ? 'byproduct' : (isset($branch) ? 'bybranch' : 'bymodule');
$removeLink = inlink('story', "executionID=$execution->id&orderBy=$orderBy&type=$removeType&param=0&recTotal=0&recPerPage={$pager->recPerPage}");
$removeLink = inlink('story', "executionID=$execution->id&storyType=$storyType&orderBy=$orderBy&type=$removeType&param=0&recTotal=0&recPerPage={$pager->recPerPage}");
$removeBtn = html::a($removeLink, "<i class='icon icon-sm icon-close'></i>", '', "class='text-muted'");
}
?>
@@ -57,20 +66,22 @@
<?php $active = $type == $featureType ? 'btn-active-text' : '';?>
<?php $label = "<span class='text'>$label</span>";?>
<?php if($type == $featureType) $label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";?>
<?php echo html::a(inlink('story', "executionID=$execution->id&orderBy=order_desc&type=$featureType"), $label, '', "class='btn btn-link $active'");?>
<?php echo html::a(inlink('story', "executionID=$execution->id&storyType=$storyType&orderBy=order_desc&type=$featureType"), $label, '', "class='btn btn-link $active'");?>
<?php endforeach;?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->product->searchStory;?></a>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('execution', 'storykanban')):?>
<?php if(common::hasPriv('execution', 'storykanban') and $storyType == 'story'):?>
<div class="btn-group panel-actions">
<?php echo html::a($this->createLink('execution', 'story', "executionID=$execution->id&orderBy=order_desc&type=all"), "<i class='icon-list'></i> &nbsp;", '', "class='btn btn-icon text-primary switchBtn' title='{$lang->execution->list}' data-type='bylist'");?>
<?php echo html::a($this->createLink('execution', 'story', "executionID=$execution->id&storyType=$storyType&orderBy=order_desc&type=all"), "<i class='icon-list'></i> &nbsp;", '', "class='btn btn-icon text-primary switchBtn' title='{$lang->execution->list}' data-type='bylist'");?>
<?php echo html::a($this->createLink('execution', 'storykanban', "executionID=$execution->id"), "<i class='icon-kanban'></i> &nbsp;", '', "class='btn btn-icon switchBtn' title='{$lang->execution->kanban}' data-type='bykanban'");?>
</div>
<?php endif;?>
<?php
common::printLink('story', 'export', "productID=$productID&orderBy=id_desc&executionID=$execution->id", "<i class='icon icon-export muted'></i> " . $lang->story->export, '', "class='btn btn-link export iframe' data-app='execution'");
if($productID) common::printIcon('story', 'report', "productID=$productID&branchID=&storyType=$storyType&browseType=$type&moduleID=$param&chartType=pie&projectID=$execution->id", '', 'button', 'bar-chart muted');
common::printLink('story', 'export', "productID=$productID&orderBy=id_desc&executionID=$execution->id", "<i class='icon icon-export muted'></i> " . $lang->story->export, '', "class='btn btn-link export iframe'");
$canLinkStory = $execution->hasProduct or $execution->multiple;
if(common::canModify('execution', $execution))
{
$this->lang->story->create = $this->lang->execution->createStory;
@@ -78,8 +89,8 @@
if($productID)
{
$storyModuleID = (int)$this->cookie->storyModuleParam;
$createStoryLink = $this->createLink('story', 'create', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id");
$batchCreateLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id");
$createStoryLink = $this->createLink('story', 'create', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id&bugID=0&planID=0&todoID=0&extra=&storyType=$storyType");
$batchCreateLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id&plan=0&storyType=$storyType");
$buttonLink = '';
$buttonTitle = '';
@@ -96,14 +107,14 @@
$hidden = empty($buttonLink) ? 'hidden' : '';
echo "<div class='btn-group dropdown' title='{$buttonTitle}'>";
echo html::a($buttonLink, "<i class='icon icon-plus'></i> $buttonTitle", '', "class='btn btn-secondary $hidden' data-app='execution'");
echo html::a($buttonLink, "<i class='icon icon-plus'></i> $buttonTitle", '', "class='btn btn-secondary $hidden' data-app='$app->tab'");
if($common::hasPriv('story', 'create') and common::hasPriv('story', 'batchCreate'))
{
if(!($isAllProduct and count($products) > 1)) echo "<button type='button' class='btn btn-secondary dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>";
echo "<ul class='dropdown-menu pull-right'>";
echo '<li>' . html::a($createStoryLink, $lang->story->create, '', "data-app='execution'") . '</li>';
echo '<li>' . html::a($batchCreateLink, $lang->story->batchCreate, '', "data-app='execution'") . '</li>';
echo '<li>' . html::a($createStoryLink, $lang->story->create, '', "data-app=$app->tab") . '</li>';
echo '<li>' . html::a($batchCreateLink, $lang->story->batchCreate, '', "data-app=$app->tab") . '</li>';
echo '</ul>';
}
@@ -115,7 +126,7 @@
$wizardParams = helper::safe64Encode("execution=$execution->id");
echo html::a($this->createLink('tutorial', 'wizard', "module=execution&method=linkStory&params=$wizardParams"), "<i class='icon-link'></i> {$lang->execution->linkStory}",'', "class='btn btn-link link-story-btn'");
}
else
elseif($canLinkStory) // The none-product and single execution cann't link stories.
{
echo "<div class='btn-group dropdown'>";
@@ -137,7 +148,7 @@
$hidden = empty($buttonLink) ? 'hidden' : '';
echo html::a($buttonLink, "<i class='icon-link'></i> $buttonTitle", '', "class='btn btn-primary $hidden' $dataToggle");
if(common::hasPriv('execution', 'linkStory') and common::hasPriv('execution', 'importPlanStories'))
if(common::hasPriv('execution', 'linkStory') and common::hasPriv('execution', 'importPlanStories') and ($execution->hasProduct or $execution->type == 'sprint'))
{
echo "<button type='button' class='btn btn-primary dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>";
echo "<ul class='dropdown-menu pull-right'>";
@@ -165,7 +176,10 @@
<div class="sidebar-toggle"><i class="icon icon-angle-left"></i></div>
<div class="cell">
<?php echo $moduleTree;?>
<div class="text-center"></div>
<div class="text-center">
<?php if($productID and !$execution->hasProduct and !$execution->multiple) common::printLink('tree', 'browse', "rootID=$productID&view=story&currentModuleID=0&branch=all", $lang->tree->manage, '', "class='btn btn-info btn-wide'");?>
<hr class="space-sm" />
</div>
</div>
</div>
<div class="main-col">
@@ -177,9 +191,29 @@
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->story->noStory;?></span>
<?php if(common::canModify('execution', $execution) and common::hasPriv('execution', 'linkStory')):?>
<?php echo html::a($this->createLink('execution', 'linkStory', "execution=$execution->id"), "<i class='icon icon-link'></i> " . $lang->execution->linkStory, '', "class='btn btn-info'");?>
<?php endif;?>
<?php
if(common::canModify('execution', $execution))
{
if($canLinkStory && common::hasPriv('execution', 'linkStory'))
{
echo html::a($this->createLink('execution', 'linkStory', "execution=$execution->id"), "<i class='icon icon-link'></i> " . $lang->execution->linkStory, '', "class='btn btn-info'");
}
else
{
$storyModuleID = (int)$this->cookie->storyModuleParam;
if(common::hasPriv('story', 'create'))
{
$createStoryLink = $this->createLink('story', 'create', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id&bugID=0&planID=0&todoID=0&extra=&storyType=$storyType");
echo html::a($createStoryLink, "<i class='icon icon-plus'></i> " . $lang->execution->createStory, '', "class='btn btn-info' data-app=$app->tab");
}
elseif(common::hasPriv('story', 'batchCreate'))
{
$batchCreateLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=0&moduleID={$storyModuleID}&story=0&execution=$execution->id&plan=0&storyType=$storyType");
echo html::a($batchCreateLink, "<i class='icon icon-plus'></i> " . $lang->story->batchCreate, '', "class='btn btn-info' data-app=$app->tab");
}
}
}
?>
</p>
</div>
<?php else:?>
@@ -190,6 +224,12 @@
$vars = "executionID={$execution->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
if($useDatatable) include '../../common/view/datatable.html.php';
if(!$execution->hasProduct and !$execution->multiple)
{
$planKey = array_search('plan', $config->story->datatable->defaultField);
if($planKey) unset($config->story->datatable->defaultField[$planKey]);
}
$setting = $this->datatable->getSetting('execution');
$widths = $this->datatable->setFixedFieldWidth($setting);
$columns = 0;
@@ -212,6 +252,7 @@
<?php
foreach($setting as $key => $value)
{
if(!$execution->hasProduct and !$execution->multiple and $value->id == 'plan') continue;
if($value->show)
{
$this->datatable->printHead($value, $orderBy, $vars, $canBatchAction);
@@ -229,10 +270,27 @@
<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)?>'>
<?php foreach($setting as $key => $value)
{
$this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', 'story', $execution, $showBranch);
if(!$execution->hasProduct and !$execution->multiple and $value->id == 'plan') continue;
$this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $execution, $showBranch);
}
?>
</tr>
<?php if(!empty($story->children)):?>
<?php $i = 0;?>
<?php foreach($story->children as $key => $child):?>
<?php $child->from = 'execution';?>
<?php $class = $i == 0 ? ' table-child-top' : '';?>
<?php $class .= ($i + 1 == count($story->children)) ? ' table-child-bottom' : '';?>
<tr class='table-children<?php echo $class;?> parent-<?php echo $story->id;?>' data-id='<?php echo $child->id?>' data-status='<?php echo $child->status?>' data-estimate='<?php echo $child->estimate?>' data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
<?php foreach($setting as $key => $value)
{
if(!$execution->hasProduct and !$execution->multiple and $value->id == 'plan') continue;
$this->story->printCell($value, $child, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType, $execution);
}?>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
</tbody>
</table>
@@ -245,7 +303,7 @@
<div class='btn-group dropup'>
<?php
$disabled = $canBatchEdit ? '' : "disabled='disabled'";
$actionLink = $this->createLink('story', 'batchEdit', "productID=0&executionID=$execution->id");
$actionLink = $this->createLink('story', 'batchEdit', "productID=0&executionID=$execution->id&branch=0&storyType=$storyType");
echo html::commonButton($lang->edit, "data-form-action='$actionLink' $disabled");
?>
<?php if($canBatchToTask):?>
@@ -282,7 +340,7 @@
</div>
<?php endif;?>
<?php
if(common::hasPriv('execution', 'batchUnlinkStory'))
if($canLinkStory && common::hasPriv('execution', 'batchUnlinkStory'))
{
$actionLink = $this->createLink('execution', 'batchUnlinkStory', "executionID=$execution->id");
echo html::commonButton($lang->execution->unlinkStoryAB, "data-form-action='$actionLink'");
+5 -8
View File
@@ -10,13 +10,13 @@
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<style>
#showAverage {margin: 0;}
.chosen-container-single .chosen-single div b {top: 8px !important;}
.chosen-container .chosen-drop {bottom: auto !important;}
.pull-left {margin: 12px 0px;}
.btn-toolbar #roundBox {width:220px;}
</style>
<?php include '../../common/view/header.html.php';?>
<?php js::set('executionID', $executionID);?>
<?php js::set('storyID', $storyID);?>
<div id='mainContent' class='main-content'>
@@ -33,7 +33,7 @@
<?php else:?>
<div class='btn-toolbar pull-left'>
<?php if(!empty($rounds)):?>
<div class='input-group space w-200px'>
<div id='roundBox' class='input-group space'>
<span class='input-group-addon'><?php echo $lang->execution->selectRound?></span>
<?php echo html::select('round', $rounds, $round, "class='form-control chosen' onchange='selectRound(this.value)'");?>
</div>
@@ -70,18 +70,15 @@
<?php if(!empty($estimateInfo->estimate)):?>
<td><?php echo $estimateInfo->average;?></td>
<td class='new-estimate hide'><p id='showAverage'></p></td>
<?php echo html::hidden('average', '', "class='form-control'");?>
<?php else:?>
<td><p id='showAverage'></p></td>
<?php echo html::hidden('average', '', "class='form-control'");?>
<?php endif;?>
<?php echo html::hidden('average', '', "class='form-control'");?>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan='3' class="text-center form-actions <?php if(!empty($rounds)) echo 'hide';?>">
<?php echo html::submitButton(); ?>
</td>
<td colspan='3' class="text-center form-actions <?php if(!empty($rounds)) echo 'hide';?>"><?php echo html::submitButton();?></td>
</tr>
</tfoot>
</table>
+1 -1
View File
@@ -46,7 +46,7 @@ $account = $this->app->user->account;
$wizardParams = helper::safe64Encode("execution=$execution->id");
echo html::a($this->createLink('tutorial', 'wizard', "module=execution&method=linkStory&params=$wizardParams"), "<i class='icon-link'></i> {$lang->execution->linkStory}", '', "class='btn btn-primary'");
}
else
elseif($execution->hasProduct)
{
common::printLink('execution', 'linkStory', "execution=$execution->id", "<i class='icon icon-link'></i> " . $lang->execution->linkStory, '', "class='btn btn-primary'");
}
+7 -4
View File
@@ -130,10 +130,13 @@ body {margin-bottom: 25px;}
<button class="btn btn-link" data-toggle="dropdown"><i class="icon icon-import muted"></i> <span class="text"><?php echo $lang->import;?></span> <span class="caret"></span></button>
<ul class="dropdown-menu pull-right" id='importActionMenu'>
<?php
$class = common::hasPriv('execution', 'importTask') ? '' : "class=disabled";
$misc = common::hasPriv('execution', 'importTask') ? "class='import'" : "class=disabled";
$link = common::hasPriv('execution', 'importTask') ? $this->createLink('execution', 'importTask', "execution=$execution->id") : '#';
echo "<li $class>" . html::a($link, $lang->execution->importTask, '', $misc) . "</li>";
if($execution->multiple)
{
$class = common::hasPriv('execution', 'importTask') ? '' : "class=disabled";
$misc = common::hasPriv('execution', 'importTask') ? "class='import'" : "class=disabled";
$link = common::hasPriv('execution', 'importTask') ? $this->createLink('execution', 'importTask', "execution=$execution->id") : '#';
echo "<li $class>" . html::a($link, $lang->execution->importTask, '', $misc) . "</li>";
}
if($execution->lifetime != 'ops')
{
+1 -1
View File
@@ -91,7 +91,7 @@
$canCreateStory = ($productID and common::hasPriv('story', 'create'));
$canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate'));
$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory'));
$canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories'));
$canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories') and !$hiddenPlan);
$hasStoryButton = ($canCreateStory or $canBatchCreateStory or $canLinkStory or $canLinkStoryByPlan);
$hasTaskButton = ($canCreateTask or $canBatchCreateTask or $canImportBug);
$hasBugButton = ($canCreateBug or $canBatchCreateBug);
+8 -4
View File
@@ -12,9 +12,13 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('confirmDelete', $lang->testtask->confirmDelete)?>
<?php $hideProduct = (isset($project->hasProduct) and $project->hasProduct == '0');?>
<?php if(!$hideProduct):?>
<style>.table-footer {margin-left: 205px}</style>
<?php endif;?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php if(!empty($tasks)):?>
<?php if(!empty($tasks) and !$hideProduct):?>
<div class="pull-left table-group-btns">
<button type="button" class="btn btn-link group-collapse-all"><?php echo $lang->testtask->collapseAll;?> <i class="icon-fold-all muted"></i></button>
<button type="button" class="btn btn-link group-expand-all"><?php echo $lang->testtask->expandAll;?> <i class="icon-unfold-all muted"></i></button>
@@ -55,8 +59,8 @@ $doneCount = 0;
<thead>
<?php $vars = "executionID=$executionID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<?php $canTestReport = ($canBeChanged and common::hasPriv('testreport', 'browse'));?>
<tr class='<?php if($total) echo 'divider'; ?>'>
<th class='c-side text-center'><?php common::printOrderLink('product', $orderBy, $vars, $lang->testtask->product);?></th>
<tr class='<?php if($total and !$hideProduct) echo 'divider'; ?>'>
<th class='c-side text-center <?php if($hideProduct) echo 'hide';?>'><?php common::printOrderLink('product', $orderBy, $vars, $lang->testtask->product);?></th>
<th class="c-id">
<?php if($canTestReport):?>
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
@@ -84,7 +88,7 @@ $doneCount = 0;
<?php if($task->status == 'done') $doneCount ++;?>
<tr data-id='<?php echo $product;?>' <?php if($task == reset($productTasks)) echo "class='divider-top'";?> data-status='<?php echo $task->status;?>'>
<?php if($task == reset($productTasks)):?>
<td rowspan='<?php echo count($productTasks);?>' class='c-side text-left group-toggle'>
<td rowspan='<?php echo count($productTasks);?>' class='c-side text-left group-toggle <?php if($hideProduct) echo 'hide';?>'>
<a class='text-primary' title='<?php echo $productName;?>'><i class='icon icon-caret-down'></i> <?php echo $productName;?></a>
<div class='small'><span class='text-muted'><?php echo $lang->testtask->allTasks;?></span> <?php echo count($productTasks);?></div>
</td>
+1 -1
View File
@@ -5,7 +5,7 @@
<?php if($execution->lifetime != 'ops') echo html::a($this->createLink('execution', 'linkstory', "executionID=$executionID"), $lang->execution->linkStory, '', "class='btn' data-app='execution'");?>
<?php echo html::a($this->createLink('task', 'create', "execution=$executionID"), $lang->execution->createTask, '', "class='btn' data-app='execution'");?>
<?php echo html::a($this->createLink('execution', 'task', "executionID=$executionID"), $lang->execution->goback, '', "class='btn' data-app='execution'");?>
<?php if($this->config->systemMode == 'new') echo html::a('javascript:void(0)', $lang->execution->gobackExecution, '', "class='btn' onclick='closeTipsModal($projectID)' data-app='project'");?>
<?php echo html::a('javascript:void(0)', $lang->execution->gobackExecution, '', "class='btn' onclick='closeTipsModal($projectID)' data-app='project'");?>
</div>
</div>
<script>
+2 -2
View File
@@ -42,7 +42,7 @@
<div class="detail-content">
<table class="table table-data">
<tbody>
<?php if($this->config->vision != 'lite'):?>
<?php if($this->config->vision != 'lite' and empty($product->shadow)):?>
<tr>
<th class='w-100px'><?php echo $lang->story->product;?></th>
<td><?php echo html::a($this->createLink('product', 'view', "productID=$story->product"), $product->name, '', "data-app='product'");?></td>
@@ -56,7 +56,7 @@
<?php endif;?>
<?php if($this->config->vision != 'lite'):?>
<tr>
<th><?php echo $lang->story->module;?></th>
<th class='w-100px'><?php echo $lang->story->module;?></th>
<?php
$moduleTitle = '';
ob_start();
+4 -4
View File
@@ -288,7 +288,7 @@
</p>
</div>
</div>
<?php if($this->config->systemMode == 'new'):?>
<?php if($this->config->systemMode == 'ALM'):?>
<div class="detail">
<div class="detail-title">
<strong><?php echo $lang->project->parent;?></strong>
@@ -312,7 +312,6 @@
</div>
</div>
<?php endif;?>
<?php if($this->config->systemMode == 'new'):?>
<div class="detail">
<div class="detail-title">
<strong><?php echo $lang->project->project;?></strong>
@@ -326,8 +325,7 @@
</div>
</div>
</div>
<?php endif;?>
<?php if(!in_array($execution->attribute, array('request', 'design', 'review'))): ?>
<?php if(!in_array($execution->attribute, array('request', 'design', 'review')) and $execution->projectInfo->hasProduct): ?>
<div class="detail">
<div class="detail-title">
<strong><?php echo $lang->execution->manageProducts;?></strong>
@@ -347,6 +345,7 @@
</div>
</div>
<?php endif; ?>
<?php if($execution->projectInfo->hasProduct or $execution->projectInfo->model == 'scrum'):?>
<div class="detail">
<div class="detail-title"><strong><?php echo $lang->execution->linkPlan;?></strong></div>
<div class="detail-content">
@@ -367,6 +366,7 @@
</div>
</div>
</div>
<?php endif;?>
<div class='detail'>
<div class='detail-title'><strong><?php echo $lang->execution->lblStats;?></strong></div>
<div class="detail-content">