This commit is contained in:
zhujinyong
2022-05-24 09:16:00 +08:00
70 changed files with 733 additions and 334 deletions
+2 -1
View File
@@ -175,7 +175,8 @@ class action extends control
{
$story = $this->loadModel('story')->getById($objectID);
$executions = explode(',', $this->app->user->view->sprints);
if(!array_intersect(array_keys($story->executions), $executions)) return print(js::error($this->lang->error->accessDenied));
$products = explode(',', $this->app->user->view->products);
if(!array_intersect(array_keys($story->executions), $executions) and !in_array($story->product, $products)) return print(js::error($this->lang->error->accessDenied));
}
$actionID = $this->action->create($objectType, $objectID, 'Commented', $this->post->comment);
+1 -1
View File
@@ -128,7 +128,7 @@ $lang->my->dividerMenu = ',work,dynamic,';
/* Program menu. */
$lang->program->homeMenu = new stdclass();
$lang->program->homeMenu->browse = array('link' => "{$lang->program->list}|program|browse|", 'alias' => 'create,edit');
$lang->program->homeMenu->browse = array('link' => "{$lang->program->list}|program|browse|", 'alias' => 'create,edit', 'subModule' => 'project');
$lang->program->homeMenu->kanban = array('link' => "{$lang->program->kanban}|program|kanban|");
$lang->program->menu = new stdclass();
+7 -2
View File
@@ -450,7 +450,7 @@ class commonModel extends model
echo '<li class="user-tutorial">' . html::a(helper::createLink('tutorial', 'start'), "<i class='icon icon-guide'></i> " . $lang->tutorialAB, '', "class='iframe' data-class-name='modal-inverse' data-width='800' data-headerless='true' data-backdrop='true' data-keyboard='true'") . '</li>';
}
echo '<li>' . html::a(helper::createLink('my', 'preference', '', '', true), "<i class='icon icon-controls'></i> " . $lang->preference, '', "class='iframe' data-width='700'") . '</li>';
echo '<li>' . html::a(helper::createLink('my', 'preference', 'showTip=false', '', true), "<i class='icon icon-controls'></i> " . $lang->preference, '', "class='iframe' data-width='700'") . '</li>';
}
if(common::hasPriv('my', 'changePassword')) echo '<li>' . html::a(helper::createLink('my', 'changepassword', '', '', true), "<i class='icon icon-cog-outline'></i> " . $lang->changePassword, '', "class='iframe' data-width='600'") . '</li>';
@@ -664,7 +664,12 @@ class commonModel extends model
$params = "productID=$productID&branch=&moduleID=0&from=&param=0&storyID=0&extras=from=global";
break;
case 'execution':
$params = "projectID=&executionID=0&copyExecutionID=0&planID=0&confirm=no&productID=0&extra=from=global";
$projectID = 0;
if(in_array($app->tab, array('project', 'execution')) and isset($lang->switcherMenu))
{
$projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0;
}
$params = "projectID={$projectID}&executionID=0&copyExecutionID=0&planID=0&confirm=no&productID=0&extra=from=global";
break;
case 'product':
$params = "programID=&extra=from=global";
+1
View File
@@ -1109,6 +1109,7 @@ class doc extends control
public function tableContents($type, $objectID = 0, $libID = 0)
{
list($libs, $libID, $object, $objectID) = $this->doc->setMenuByType($type, $objectID, $libID);
$this->session->set('createProjectLocate', $this->app->getURI(true), 'doc');
$libID = (int)$libID;
+12 -2
View File
@@ -679,7 +679,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, $orderBy = 'order_asc', $type = 'all', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
{
/* Load these models. */
$this->loadModel('story');
@@ -1626,6 +1626,7 @@ class execution extends control
/* If the story of the product which linked the execution, you don't allow to remove the product. */
$unmodifiableProducts = array();
$unmodifiableBranches = array();
$linkedStoryIDList = array();
foreach($linkedProducts as $productID => $linkedProduct)
{
if(!isset($allProducts[$productID])) $allProducts[$productID] = $linkedProduct->name;
@@ -1639,6 +1640,7 @@ class execution extends control
{
array_push($unmodifiableProducts, $productID);
array_push($unmodifiableBranches, $branchID);
$linkedStoryIDList[$productID][$branchID] = $executionStories[$productID][$branchID]->storyIDList;
}
}
}
@@ -1672,6 +1674,7 @@ class execution extends control
$this->view->allProducts = $allProducts;
$this->view->linkedProducts = $linkedProducts;
$this->view->linkedBranches = $linkedBranches;
$this->view->linkedStoryIDList = $linkedStoryIDList;
$this->view->branches = $branches;
$this->view->unmodifiableProducts = $unmodifiableProducts;
$this->view->unmodifiableBranches = $unmodifiableBranches;
@@ -2655,6 +2658,7 @@ class execution extends control
/* If the story of the product which linked the execution, you don't allow to remove the product. */
$unmodifiableProducts = array();
$unmodifiableBranches = array();
$linkedStoryIDList = array();
foreach($linkedProducts as $productID => $linkedProduct)
{
$linkedBranches[$productID] = array();
@@ -2666,6 +2670,7 @@ class execution extends control
{
array_push($unmodifiableProducts, $productID);
array_push($unmodifiableBranches, $branchID);
$linkedStoryIDList[$productID][$branchID] = $executionStories[$productID][$branchID]->storyIDList;
}
}
}
@@ -2679,6 +2684,7 @@ class execution extends control
$this->view->unmodifiableProducts = $unmodifiableProducts;
$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');
@@ -3152,8 +3158,12 @@ class execution extends control
*/
public function tips($executionID)
{
$this->view->execution = $this->execution->getById($executionID);
$execution = $this->execution->getById($executionID);
$projectID = $execution->project;
$this->view->execution = $execution;
$this->view->executionID = $executionID;
$this->view->projectID = $projectID;
$this->display('execution', 'tips');
}
+1 -1
View File
@@ -1,2 +1,2 @@
#fromproject_chosen .chosen-single {width: 220px;}
.c-name {width: 150px;}
.c-name {width: 200px;}
+7 -3
View File
@@ -45,7 +45,9 @@ $(function()
if(isExistedProduct != -1 && productType == 'normal')
{
$(this).prop('disabled', true).trigger("chosen:updated");
$(this).siblings('div').find('span').attr('title', tip);
var productTip = tip.replace('%s', linkedStoryIDList[$(this).attr('data-last')][0]);
$(this).siblings('div').find('span').attr('title', productTip);
}
});
@@ -55,11 +57,13 @@ $(function()
if(isExistedBranch != -1)
{
var $product = $(this).closest('.has-branch').find("[name^='products']");
if($.inArray($product.val(), unmodifiableProducts) != -1)
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");
$product.siblings('div').find('span').attr('title', tip);
var productTip = tip.replace('%s', linkedStoryIDList[$product.val()][$(this).attr('data-last')]);
$product.siblings('div').find('span').attr('title', productTip);
}
}
});
+1 -1
View File
@@ -10,7 +10,7 @@ $(function()
$target.hide();
$target.fadeIn(1000);
order = 'order_asc'
history.pushState({}, 0, createLink('project', 'story', "executionID=" + executionID + '&orderBy=' + order));
history.pushState({}, 0, createLink('execution', 'story', "executionID=" + executionID + '&orderBy=' + order));
});
});
+3 -2
View File
@@ -344,7 +344,7 @@ $lang->execution->confirmUnlinkStory = "After {$lang->SRCommon} is remo
$lang->execution->confirmSync = "After modifying the project, in order to maintain the consistency of data, the data of products, requirements, teams and whitelist associated with the implementation will be synchronized to the new project. Please know.";
$lang->execution->confirmUnlinkExecutionStory = "Do you want to unlink this Story from the execution?";
$lang->execution->notAllowedUnlinkStory = "This {$lang->SRCommon} is linked to the {$lang->executionCommon} of the execution. Remove it from the {$lang->executionCommon}, then try again.";
$lang->execution->notAllowRemoveProducts = "The story of this product is linked with the {$lang->executionCommon}. Unlink it before doing any action.";
$lang->execution->notAllowRemoveProducts = "The story %s of this product is linked with the {$lang->executionCommon}. Unlink it before doing any action.";
$lang->execution->errorNoLinkedProducts = "No {$lang->productCommon} is linked to {$lang->executionCommon}. You will be directed to {$lang->productCommon} page to link one.";
$lang->execution->errorSameProducts = "{$lang->executionCommon} cannot be linked to the same {$lang->productCommon} twice.";
$lang->execution->errorSameBranches = "{$lang->executionCommon} cannot be linked to the same branch twice";
@@ -358,7 +358,8 @@ $lang->execution->afterInfo = "{$lang->executionCommon} is cre
$lang->execution->setTeam = 'Set Team';
$lang->execution->linkStory = 'Link Story';
$lang->execution->createTask = 'Create Task';
$lang->execution->goback = "Go Back";
$lang->execution->goback = "Go Back Task List";
$lang->execution->gobackExecution = "Go Back Executioni List";
$lang->execution->noweekend = 'Exclude Weekend';
$lang->execution->nodelay = 'Exclude Delay Date';
$lang->execution->withweekend = 'Include Weekend';
+2 -1
View File
@@ -344,7 +344,7 @@ $lang->execution->confirmUnlinkStory = "移除该{$lang->SRCommon}后
$lang->execution->confirmSync = "修改所属项目后,为了保持数据的一致性,该执行所关联的产品、需求、团队和白名单数据将会同步到新的项目中,请知悉。";
$lang->execution->confirmUnlinkExecutionStory = "您确定从该项目中移除该{$lang->SRCommon}吗?";
$lang->execution->notAllowedUnlinkStory = "{$lang->SRCommon}已经与项目下{$lang->executionCommon}相关联,请从{$lang->executionCommon}中移除后再操作。";
$lang->execution->notAllowRemoveProducts = "{$lang->productCommon}中的{$lang->SRCommon}已与该{$lang->executionCommon}进行了关联,请取消关联后再操作。";
$lang->execution->notAllowRemoveProducts = "{$lang->productCommon}中的{$lang->SRCommon}%s已与该{$lang->executionCommon}进行了关联,请取消关联后再操作。";
$lang->execution->errorNoLinkedProducts = "{$lang->executionCommon}没有关联的{$lang->productCommon},系统将转到{$lang->productCommon}关联页面";
$lang->execution->errorSameProducts = "{$lang->executionCommon}不能关联多个相同的{$lang->productCommon}";
$lang->execution->errorSameBranches = "{$lang->executionCommon}不能关联多个相同的分支。";
@@ -359,6 +359,7 @@ $lang->execution->setTeam = '设置团队';
$lang->execution->linkStory = "关联{$lang->SRCommon}";
$lang->execution->createTask = '创建任务';
$lang->execution->goback = "返回任务列表";
$lang->execution->gobackExecution = "返回迭代列表";
$lang->execution->noweekend = '去除周末';
$lang->execution->nodelay = '去除延期日期';
$lang->execution->withweekend = '显示周末';
+8 -12
View File
@@ -1929,18 +1929,14 @@ class executionModel extends model
*/
public function getToImport($executionIds, $type)
{
$executions = $this->dao->select('*')->from(TABLE_EXECUTION)
->where('id')->in($executionIds)
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->andWhere('type')->eq($type)
->andWhere('deleted')->eq(0)
->orderBy('id desc')
->fetchAll('id');
$pairs = array();
$now = date('Y-m-d');
foreach($executions as $id => $execution) $pairs[$id] = $execution->name;
return $pairs;
return $this->dao->select('t1.id,concat_ws(" / ", t2.name, t1.name) as name')->from(TABLE_EXECUTION)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t2.id=t1.project')
->where('t1.id')->in($executionIds)
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
->andWhere('t1.type')->eq($type)
->andWhere('t1.deleted')->eq(0)
->orderBy('t1.id desc')
->fetchPairs('id', 'name');
}
/**
+1 -1
View File
@@ -15,7 +15,7 @@
<?php $defaultURL = $this->createLink('execution', 'task', "execution=$executionID");?>
<?php include '../../common/view/header.html.php';?>
<body>
<div class='modal-dialog mw-500px' id='tipsModal'>
<div class='modal-dialog mw-700px' id='tipsModal'>
<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>
+1
View File
@@ -218,6 +218,7 @@
<?php js::set('errorSameBranches', $lang->execution->errorSameBranches);?>
<?php js::set('unmodifiableProducts',$unmodifiableProducts);?>
<?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);?>
+1 -1
View File
@@ -53,7 +53,7 @@
</div>
<?php printf('%03d', $task->id);?>
</td>
<td><?php echo $executions[$task->execution];?></td>
<td title="<?php echo $executions[$task->execution];?>"><?php echo $executions[$task->execution];?></td>
<td><span class='label-pri label-pri-<?php echo $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri, $task->pri);?>'><?php echo $task->pri == '0' ? '' : zget($lang->task->priList, $task->pri, $task->pri);?></span></td>
<td class='text-left nobr'><?php if(!common::printLink('task', 'view', "task=$task->id", $task->name)) echo $task->name;?></td>
<td <?php echo $class;?>><?php echo $task->assignedToRealName;?></td>
@@ -28,9 +28,9 @@
<?php foreach($allProducts as $productID => $productName):?>
<?php if(isset($linkedProducts[$productID])):?>
<?php foreach($linkedBranches[$productID] as $branchID):?>
<?php if(($execution->grade < 2 and in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches))) $attr = "disabled='disabled'";?>
<?php if(($execution->grade < 2 and !(in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches)))) $attr = '';?>
<?php $title = (in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches)) ? $lang->execution->notAllowRemoveProducts : $productName;?>
<?php if(($execution->grade < 2 and in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches)) and !empty($linkedStoryIDList[$productID][$branchID])) $attr = "disabled='disabled'";?>
<?php if($execution->grade < 2 and (!(in_array($productID, $unmodifiableProducts) and in_array($branchID, $unmodifiableBranches)) or empty($linkedStoryIDList[$productID][$branchID]))) $attr = '';?>
<?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' : '')?>'>
+2 -2
View File
@@ -46,8 +46,8 @@
<?php
if(common::hasPriv('execution', 'story'))
{
echo html::a($this->createLink('execution', 'story', "executionID=$execution->id&orderBy=order_desc&type=all"), "<span class='text'>{$lang->story->allStories}</span>" . ($type == 'all' ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link" . ($type == 'all' ? " btn-active-text" : '') . "'");
echo html::a($this->createLink('execution', 'story', "executionID=$execution->id&orderBy=order_desc&type=unclosed"), "<span class='text'>{$lang->story->unclosed}</span>" . ($type == 'unclosed' ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link" . ($type == 'unclosed' ? " btn-active-text" : '') . "'");
echo html::a($this->createLink('execution', 'story', "executionID=$execution->id&orderBy=order_asc&type=all"), "<span class='text'>{$lang->story->allStories}</span>" . ($type == 'all' ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link" . ($type == 'all' ? " btn-active-text" : '') . "'");
echo html::a($this->createLink('execution', 'story', "executionID=$execution->id&orderBy=order_asc&type=unclosed"), "<span class='text'>{$lang->story->unclosed}</span>" . ($type == 'unclosed' ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link" . ($type == 'unclosed' ? " btn-active-text" : '') . "'");
}
if(common::hasPriv('execution', 'storykanban')) echo html::a($this->createLink('execution', 'storykanban', "executionID=$execution->id"), "<span class='text'>{$lang->execution->kanban}</span>", '', "class='btn btn-link'");
?>
+2 -1
View File
@@ -1,9 +1,10 @@
<div style='margin: 0 auto; max-width: 400px'>
<div style='margin: 0 auto; max-width: 580px'>
<p><strong><?php echo $lang->execution->afterInfo;?></strong></p>
<div>
<?php echo html::a($this->createLink('execution', 'team', "executionID=$executionID"), $lang->execution->setTeam, '', "class='btn' data-app='execution'");?>
<?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 echo html::a($this->createLink('project', 'execution', "status=all&projectID=$projectID"), $lang->execution->gobackExecution, '', "class='btn' data-app='project'");?>
</div>
</div>
+1 -1
View File
@@ -1329,7 +1329,7 @@ class kanban extends control
$cards = $this->kanban->getCardsByObject('region', $regionID, 1);
foreach($this->config->kanban->fromType as $fromType)
{
$cards = $this->kanban->getImportedCards($region->kanban, $cards, $fromType, 1);
$cards = $this->kanban->getImportedCards($region->kanban, $cards, $fromType, 1, $regionID);
}
$this->view->kanban = $this->kanban->getByID($region->kanban);
+6 -2
View File
@@ -1114,10 +1114,11 @@ class kanbanModel extends model
* @param object $cards
* @param string $fromType
* @param int $archived
* @param int $regionID
* @access public
* @return array
*/
public function getImportedCards($kanbanID, $cards, $fromType, $archived = 0)
public function getImportedCards($kanbanID, $cards, $fromType, $archived = 0, $regionID = 0)
{
/* Get imported cards based on imported object type. */
$objectCards = $this->dao->select('*')->from(TABLE_KANBANCARD)
@@ -1125,6 +1126,7 @@ class kanbanModel extends model
->andWhere('kanban')->eq($kanbanID)
->andWhere('archived')->eq($archived)
->andWhere('fromType')->eq($fromType)
->beginIF($regionID)->andWhere('region')->eq($regionID)->fi()
->fetchGroup('fromID', 'id');
if(!empty($objectCards))
@@ -1519,7 +1521,9 @@ class kanbanModel extends model
if($browseType == 'task')
{
$cardData['name'] = $object->name;
$cardData['name'] = $object->name;
$cardData['status'] = $object->status;
$cardData['left'] = $object->left;
}
else
{
+2 -1
View File
@@ -1205,7 +1205,7 @@ EOF;
* @access public
* @return void
*/
public function preference()
public function preference($showTip = true)
{
$this->loadModel('setting');
@@ -1221,6 +1221,7 @@ EOF;
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->preference;
$this->view->position[] = $this->lang->my->preference;
$this->view->showTip = $showTip;
$this->view->URSRList = $this->loadModel('custom')->getURSRPairs();
$this->view->URSR = $this->setting->getURSR();
+1
View File
@@ -0,0 +1 @@
.tip {margin-top: 10px;}
+1
View File
@@ -17,3 +17,4 @@ td.delayed {background: #e84e0f !important; color: white;}
.c-hours {width: 50px;}
.c-status, .c-date {width: 70px;}
.c-project {width: 150px;}
.c-name {width:90px}
+1
View File
@@ -42,6 +42,7 @@ $lang->my->testtask = 'My Test Task';
$lang->my->testcase = 'My Case';
$lang->my->storyConcept = 'Story Concept';
$lang->my->pri = 'Priority';
$lang->my->alert = 'You can click on your profile at the top right and select "Preference" to modify your information. ';
$lang->my->indexAction = 'My Index';
$lang->my->calendarAction = 'My Calendar';
+1
View File
@@ -42,6 +42,7 @@ $lang->my->testtask = '我的测试单';
$lang->my->testcase = '我的用例';
$lang->my->storyConcept = $config->URAndSR ? '默认需求概念组合' : '默认需求概念';
$lang->my->pri = '优先级';
$lang->my->alert = '后续您可以点击右上方的头像,选择“个性化设置”修改信息。';
$lang->my->indexAction = '地盘仪表盘';
$lang->my->calendarAction = '我的日程';
+3 -13
View File
@@ -343,20 +343,10 @@ class myModel extends model
if($objectType == 'task')
{
$projectList = array();
$executionList = array();
foreach($objectList as $task)
{
$projectList[$task->project] = $task->project;
$executionList[$task->execution] = $task->execution;
}
$objectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->in($projectList)->orWhere('id')->in($executionList)->fetchPairs('id');
foreach($objectList as $task)
{
$task->projectName = zget($objectPairs, $task->project, '');
$task->executionName = zget($objectPairs, $task->execution, '');
}
foreach($objectList as $task) $executionList[$task->execution] = $task->execution;
$objectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->in($executionList)->fetchPairs('id');
foreach($objectList as $task) $task->executionName = zget($objectPairs, $task->execution, '');
if($objectList) return $this->loadModel('task')->processTasks($objectList);
return $objectList;
+1 -1
View File
@@ -74,7 +74,7 @@
<th class='c-user'><?php common::printOrderLink('resolvedBy', $orderBy, $vars, $lang->bug->resolvedByAB);?></th>
<?php endif;?>
<th class='c-resolution'><?php common::printOrderLink('resolution', $orderBy, $vars, $lang->bug->resolutionAB);?></th>
<th class='c-actions-5'><?php echo $lang->actions;?></th>
<th class='c-actions-5 text-center'><?php echo $lang->actions;?></th>
</tr>
</thead>
<?php
+8 -1
View File
@@ -68,7 +68,14 @@ html,body {height: 100%;}
</tr>
<?php endif;?>
<tr>
<td colspan='2' class='text-center form-actions'><?php echo html::submitButton();?></td>
<td colspan='2' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if($showTip == 'true'):?>
<div>
<p class='text-muted tip'><?php echo $lang->my->alert;?></p>
</div>
<?php endif;?>
</td>
</tr>
</table>
</form>
+1 -1
View File
@@ -66,7 +66,7 @@
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='c-actions-6'> <?php echo $lang->actions;?></th>
<th class='c-actions-6 text-center'> <?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
+1 -1
View File
@@ -67,7 +67,7 @@
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='c-actions-6'><?php echo $lang->actions;?></th>
<th class="c-actions-6 text-center"><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
+162 -160
View File
@@ -38,196 +38,198 @@
<form id='myTaskForm' class="main-table table-task skip-iframe-modal" method="post">
<?php $canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');?>
<?php $canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');?>
<table class="table has-sort-head table-fixed" id='taskTable'>
<?php $vars = "mode=$mode&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
<thead>
<tr>
<th class="c-id">
<?php if($canBatchEdit or $canBatchClose):?>
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-pri' title=<?php echo $lang->task->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-name'><?php common::printOrderLink('name', $orderBy, $vars, $lang->task->name);?></th>
<?php if($config->systemMode == 'new'):?>
<th class='c-project'><?php common::printOrderLink('project', $orderBy, $vars, $lang->my->projects);?></th>
<th class='c-project'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->task->execution);?></th>
<?php else:?>
<th class='c-project'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->my->executions);?></th>
<?php endif;?>
<?php if($type != 'openedBy'): ?>
<th class='c-user'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<?php endif;?>
<th class='c-date text-center'><?php common::printOrderLink('deadline', $orderBy, $vars, $lang->task->deadlineAB);?></th>
<?php if($type != 'assignedTo'): ?>
<th class='c-user'><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->task->assignedTo);?></th>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<th class='c-user'><?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedBy);?></th>
<?php endif;?>
<th class='c-hours'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
<th class='c-hours'><?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
<th class='c-hours'><?php common::printOrderLink('left', $orderBy, $vars, $lang->task->leftAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-actions-6'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody id='myTaskList'>
<?php foreach($tasks as $task):?>
<?php $canBeChanged = common::canBeChanged('task', $task);?>
<tr data-id='<?php echo $task->id;?>' data-status='<?php echo $task->status?>' data-estimate='<?php echo $task->estimate?>' data-consumed='<?php echo $task->consumed?>' data-left='<?php echo $task->left?>'>
<td class="c-id">
<?php if($canBatchEdit or $canBatchClose):?>
<div class="checkbox-primary">
<input type='checkbox' name='taskIDList[]' value='<?php echo $task->id;?>' <?php if(!$canBeChanged) echo 'disabled';?>/>
<label></label>
</div>
<?php endif;?>
<?php printf('%03d', $task->id);?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri);?></span></td>
<td class='c-name <?php if(!empty($task->children)) echo 'has-child';?>' title='<?php echo $task->name?>'>
<?php if(!empty($task->team)) echo '<span class="label label-badge label-light">' . $this->lang->task->multipleAB . '</span> ';?>
<?php
if($task->parent > 0)
{
echo '<span class="label label-badge label-light">' . $this->lang->task->childrenAB . '</span> ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}'");
}
else
{
echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->name, null, "style='color: $task->color'");
}
?>
<?php if(!empty($task->children)) echo '<a class="task-toggle" data-id="' . $task->id . '"><i class="icon icon-angle-double-right"></i></a>';?>
</td>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$task->execution]->name) ? $projects[$task->execution]->name : '';?>
<?php $projectID = isset($projects[$task->execution]->id) ? $projects[$task->execution]->id : 0;?>
<td class='c-project' title="<?php echo $projectName?>">
<?php echo ($projectName and $projectID) ? html::a($this->createLink('project', 'index', "projectID=$projectID"), $projectName) : '';?>
</td>
<?php endif;?>
<td class='c-project' title="<?php echo $task->executionName;?>"><?php echo html::a($this->createLink('execution', 'task', "executionID=$task->execution"), $task->executionName, '');?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->openedBy);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($task->delay) ? 'delayed' : '';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo substr($task->deadline, 5, 6);?></td>
<?php if($type != 'assignedTo'): ?>
<td class="c-assignedTo has-btn"> <?php $this->task->printAssignedHtml($task, $users);?></td>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->finishedBy);?></td>
<?php endif;?>
<td class='c-hours' title="<?php echo round($task->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->estimate, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->consumed, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->left, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-status'>
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<td class='c-actions'>
<?php
if($canBeChanged)
{
if($task->needConfirm)
{
$this->lang->task->confirmStoryChange = $this->lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin', '', '', '', '', $task->project);
}
else
{
$attr = isset($kanbanList[$task->execution]) ? "disabled" : '';
if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'");
common::printIcon('task', 'batchCreate', "executionID=$task->execution&storyID=$task->story&moduleID=$task->module&taskID=$task->id&ifame=true", $task, 'list', 'split', '', 'iframe', true, "data-width='95%' $attr", $this->lang->task->children);
}
}
?>
</td>
</tr>
<?php if(!empty($task->children)):?>
<?php $i = 0;?>
<?php foreach($task->children as $key => $child):?>
<?php $class = $i == 0 ? ' table-child-top' : '';?>
<?php $class .= ($i + 1 == count($task->children)) ? ' table-child-bottom' : '';?>
<tr class='table-children<?php echo $class;?> parent-<?php echo $task->id;?>' data-id='<?php echo $child->id?>' data-status='<?php echo $child->status?>' data-estimate='<?php echo $child->estimate?>' data-consumed='<?php echo $child->consumed?>' data-left='<?php echo $child->left?>'>
<td class="c-id">
<div class="table-responsive">
<table class="table has-sort-head table-fixed" id='taskTable'>
<?php $vars = "mode=$mode&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
<thead>
<tr>
<th class="c-id">
<?php if($canBatchEdit or $canBatchClose):?>
<div class="checkbox-primary">
<input type='checkbox' name='taskIDList[]' value='<?php echo $child->id;?>' <?php if(!$canBeChanged) echo 'disabled';?>/>
<div class="checkbox-primary check-all" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php endif;?>
<?php printf('%03d', $child->id);?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->task->priList, $child->pri);?>'><?php echo zget($lang->task->priList, $child->pri);?></span></td>
<td class='c-name' title='<?php echo $child->name?>'>
<?php if($child->parent > 0) echo '<span class="label label-badge label-light">' . $this->lang->task->childrenAB . '</span> ';?>
<?php echo html::a($this->createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color'");?>
</td>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-pri' title=<?php echo $lang->task->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-name'><?php common::printOrderLink('name', $orderBy, $vars, $lang->task->name);?></th>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$child->execution]->name) ? $projects[$child->execution]->name : '';?>
<?php $projectID = isset($projects[$child->execution]->id) ? $projects[$child->execution]->id : 0;?>
<td class='c-project' title="<?php echo $projectName;?>">
<?php echo ($projectName and $projectID) ? html::a($this->createLink('project', 'view', "projectID=$projectID"), $projectName) : '';?>
</td>
<th class='c-project'><?php common::printOrderLink('project', $orderBy, $vars, $lang->my->projects);?></th>
<th class='c-project'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->task->execution);?></th>
<?php else:?>
<th class='c-project'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->my->executions);?></th>
<?php endif;?>
<td class='c-project' title="<?php echo $child->projectName;?>"><?php echo html::a($this->createLink('execution', 'task', "executionID=$child->project"), $child->executionName, '');?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->openedBy);?></td>
<th class='c-user'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<?php endif;?>
<td class="text-center <?php echo isset($child->delay) ? 'delayed' : '';?>"><?php if(substr($child->deadline, 0, 4) > 0) echo substr($child->deadline, 5, 6);?></td>
<th class='c-date text-center'><?php common::printOrderLink('deadline', $orderBy, $vars, $lang->task->deadlineAB);?></th>
<?php if($type != 'assignedTo'): ?>
<td class="c-assignedTo has-btn"> <?php $this->task->printAssignedHtml($child, $users);?></td>
<th class='c-user'><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->task->assignedTo);?></th>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->finishedBy);?></td>
<th class='c-user'><?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedBy);?></th>
<?php endif;?>
<td class='c-hours' title="<?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->left, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<th class='c-hours'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
<th class='c-hours'><?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
<th class='c-hours'><?php common::printOrderLink('left', $orderBy, $vars, $lang->task->leftAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class="c-actions-6 text-center"><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody id='myTaskList'>
<?php foreach($tasks as $task):?>
<?php $canBeChanged = common::canBeChanged('task', $task);?>
<tr data-id='<?php echo $task->id;?>' data-status='<?php echo $task->status?>' data-estimate='<?php echo $task->estimate?>' data-consumed='<?php echo $task->consumed?>' data-left='<?php echo $task->left?>'>
<td class="c-id">
<?php if($canBatchEdit or $canBatchClose):?>
<div class="checkbox-primary">
<input type='checkbox' name='taskIDList[]' value='<?php echo $task->id;?>' <?php if(!$canBeChanged) echo 'disabled';?>/>
<label></label>
</div>
<?php endif;?>
<?php printf('%03d', $task->id);?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri);?></span></td>
<td class='c-name <?php if(!empty($task->children)) echo 'has-child';?>' title='<?php echo $task->name?>'>
<?php if(!empty($task->team)) echo '<span class="label label-badge label-light">' . $this->lang->task->multipleAB . '</span> ';?>
<?php
if($task->parent > 0)
{
echo '<span class="label label-badge label-light">' . $this->lang->task->childrenAB . '</span> ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}'");
}
else
{
echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->name, null, "style='color: $task->color'");
}
?>
<?php if(!empty($task->children)) echo '<a class="task-toggle" data-id="' . $task->id . '"><i class="icon icon-angle-double-right"></i></a>';?>
</td>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$task->execution]->name) ? $projects[$task->execution]->name : '';?>
<?php $projectID = isset($projects[$task->execution]->id) ? $projects[$task->execution]->id : 0;?>
<td class='c-project' title="<?php echo $projectName?>">
<?php echo ($projectName and $projectID) ? html::a($this->createLink('project', 'index', "projectID=$projectID"), $projectName) : '';?>
</td>
<?php endif;?>
<td class='c-project' title="<?php echo $task->executionName;?>"><?php echo html::a($this->createLink('execution', 'task', "executionID=$task->execution"), $task->executionName, '');?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->openedBy);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($task->delay) ? 'delayed' : '';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo substr($task->deadline, 5, 6);?></td>
<?php if($type != 'assignedTo'): ?>
<td class="c-assignedTo has-btn"> <?php $this->task->printAssignedHtml($task, $users);?></td>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->finishedBy);?></td>
<?php endif;?>
<td class='c-hours' title="<?php echo round($task->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->estimate, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->consumed, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->left, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-status'>
<?php $storyChanged = (!empty($child->storyStatus) and $child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion and !in_array($child->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$child->status}'> " . $this->processStatus('task', $child) . "</span>");?>
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<td class='c-actions'>
<?php
if($canBeChanged)
{
if($child->needConfirm)
if($task->needConfirm)
{
$this->lang->task->confirmStoryChange = $this->lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$child->id", '', 'list', '', 'hiddenwin');
common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin', '', '', '', '', $task->project);
}
else
{
if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
$attr = isset($kanbanList[$task->execution]) ? "disabled" : '';
if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, "data-width='95%'");
common::printIcon('task', 'batchCreate', "executionID=$child->execution&storyID=$child->story&moduleID=$child->module&taskID=$child->id&iframe=true", $child, 'list', 'split', '', 'iframe', true, '', $this->lang->task->children);
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'");
common::printIcon('task', 'batchCreate', "executionID=$task->execution&storyID=$task->story&moduleID=$task->module&taskID=$task->id&ifame=true", $task, 'list', 'split', '', 'iframe', true, "data-width='95%' $attr", $this->lang->task->children);
}
}
?>
</td>
</tr>
<?php $i ++;?>
<?php if(!empty($task->children)):?>
<?php $i = 0;?>
<?php foreach($task->children as $key => $child):?>
<?php $class = $i == 0 ? ' table-child-top' : '';?>
<?php $class .= ($i + 1 == count($task->children)) ? ' table-child-bottom' : '';?>
<tr class='table-children<?php echo $class;?> parent-<?php echo $task->id;?>' data-id='<?php echo $child->id?>' data-status='<?php echo $child->status?>' data-estimate='<?php echo $child->estimate?>' data-consumed='<?php echo $child->consumed?>' data-left='<?php echo $child->left?>'>
<td class="c-id">
<?php if($canBatchEdit or $canBatchClose):?>
<div class="checkbox-primary">
<input type='checkbox' name='taskIDList[]' value='<?php echo $child->id;?>' <?php if(!$canBeChanged) echo 'disabled';?>/>
<label></label>
</div>
<?php endif;?>
<?php printf('%03d', $child->id);?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->task->priList, $child->pri);?>'><?php echo zget($lang->task->priList, $child->pri);?></span></td>
<td class='c-name' title='<?php echo $child->name?>'>
<?php if($child->parent > 0) echo '<span class="label label-badge label-light">' . $this->lang->task->childrenAB . '</span> ';?>
<?php echo html::a($this->createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color'");?>
</td>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$child->execution]->name) ? $projects[$child->execution]->name : '';?>
<?php $projectID = isset($projects[$child->execution]->id) ? $projects[$child->execution]->id : 0;?>
<td class='c-project' title="<?php echo $projectName;?>">
<?php echo ($projectName and $projectID) ? html::a($this->createLink('project', 'view', "projectID=$projectID"), $projectName) : '';?>
</td>
<?php endif;?>
<td class='c-project' title="<?php echo $child->projectName;?>"><?php echo html::a($this->createLink('execution', 'task', "executionID=$child->project"), $child->executionName, '');?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->openedBy);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($child->delay) ? 'delayed' : '';?>"><?php if(substr($child->deadline, 0, 4) > 0) echo substr($child->deadline, 5, 6);?></td>
<?php if($type != 'assignedTo'): ?>
<td class="c-assignedTo has-btn"> <?php $this->task->printAssignedHtml($child, $users);?></td>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->finishedBy);?></td>
<?php endif;?>
<td class='c-hours' title="<?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->left, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-status'>
<?php $storyChanged = (!empty($child->storyStatus) and $child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion and !in_array($child->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$child->status}'> " . $this->processStatus('task', $child) . "</span>");?>
</td>
<td class='c-actions'>
<?php
if($canBeChanged)
{
if($child->needConfirm)
{
$this->lang->task->confirmStoryChange = $this->lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$child->id", '', 'list', '', 'hiddenwin');
}
else
{
if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, "data-width='95%'");
common::printIcon('task', 'batchCreate', "executionID=$child->execution&storyID=$child->story&moduleID=$child->module&taskID=$child->id&iframe=true", $child, 'list', 'split', '', 'iframe', true, '', $this->lang->task->children);
}
}
?>
</td>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
</tbody>
</table>
</tbody>
</table>
</div>
<div class="table-footer">
<?php if($canBatchClose or $canBatchEdit):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
+1 -1
View File
@@ -40,7 +40,7 @@
<th class='c-date'> <?php common::printOrderLink('begin', $orderBy, $vars, $lang->testtask->begin);?></th>
<th class='c-date'> <?php common::printOrderLink('end', $orderBy, $vars, $lang->testtask->end);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-actions-6'><?php echo $lang->actions;?></th>
<th class='c-actions-6 text-center'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
+1
View File
@@ -83,6 +83,7 @@ class product extends control
$branch = ($this->cookie->preBranch !== '' and $branch === '') ? $this->cookie->preBranch : $branch;
setcookie('preBranch', $branch, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
$this->session->set('createProjectLocate', $this->app->getURI(true), 'product');
$this->product->setMenu($productID, $branch);
+1 -1
View File
@@ -372,7 +372,7 @@ class productplan extends control
* @access public
* @return void
*/
public function view($planID = 0, $type = 'story', $orderBy = 'id_desc', $link = 'false', $param = '', $recTotal = 0, $recPerPage = 100, $pageID = 1)
public function view($planID = 0, $type = 'story', $orderBy = 'order_asc', $link = 'false', $param = '', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
$planID = (int)$planID;
$plan = $this->productplan->getByID($planID, true);
+7 -5
View File
@@ -401,6 +401,7 @@ class productplanModel extends model
->andWhere('deleted')->eq(0)
->beginIF($branches != '')->andWhere('branch')->in($branches)->fi()
->beginIF($skipParent)->andWhere('parent')->ne(-1)->fi()
->orderBy('begin desc')
->fetchAll('id');
$planPairs = array();
@@ -517,17 +518,18 @@ class productplanModel extends model
}
elseif($oldPlan->parent == -1 and $plan->begin != $this->config->productplan->future)
{
$childPlans = $this->getChildren($planID);
$minBegin = $plan->begin;
$maxEnd = $plan->end;
$plan->parent = -1;
$childPlans = $this->getChildren($planID);
$minBegin = $plan->begin;
$maxEnd = $plan->end;
foreach($childPlans as $childID => $childPlan)
{
$childPlan = isset($plans[$childID]) ? $plans[$childID] : $childPlan;
if($childPlan->begin < $minBegin) $minBegin = $childPlan->begin;
if($childPlan->end > $maxEnd) $maxEnd = $childPlan->end;
}
if($minBegin < $plan->begin and $minBegin != $this->config->productplan->future) dao::$errors['begin'] = sprintf($this->lang->productplan->beginGreaterChildTip, $planID, $plan->begin, $minBegin);
if($maxEnd > $plan->end and $maxEnd != $this->config->productplan->future) dao::$errors['end'] = sprintf($this->lang->productplan->endLetterChildTip, $planID, $plan->end, $maxEnd);
if($minBegin < $plan->begin and $minBegin != $this->config->productplan->future) dao::$errors['begin'] = sprintf($this->lang->productplan->beginGreaterChildTip, $oldPlan->title, $plan->begin, $minBegin);
if($maxEnd > $plan->end and $maxEnd != $this->config->productplan->future) dao::$errors['end'] = sprintf($this->lang->productplan->endLetterChildTip, $oldPlan->title, $plan->end, $maxEnd);
}
if(dao::isError()) return false;
+5
View File
@@ -32,6 +32,7 @@ class program extends control
$this->session->set('programList', $this->app->getURI(true), 'program');
$this->session->set('projectList', $this->app->getURI(true), 'program');
$this->session->set('createProjectLocate', $this->app->getURI(true), 'program');
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
@@ -67,9 +68,11 @@ class program extends control
/* Get PM id list. */
$accounts = array();
$hasProject = false;
foreach($programs as $program)
{
if(!empty($program->PM) and !in_array($program->PM, $accounts)) $accounts[] = $program->PM;
if($hasProject === false and $program->type != 'program') $hasProject = true;
}
$PMList = $this->loadModel('user')->getListByAccounts($accounts, 'account');
@@ -92,6 +95,7 @@ class program extends control
$this->view->programType = $programType;
$this->view->PMList = $PMList;
$this->view->progressList = $this->program->getProgressList();
$this->view->hasProject = $hasProject;
$this->display();
}
@@ -454,6 +458,7 @@ class program extends control
$uri = $this->app->getURI(true);
$this->app->session->set('programProject', $uri, 'program');
$this->app->session->set('projectList', $uri, 'program');
$this->app->session->set('createProjectLocate', $uri, 'program');
$this->loadModel('datatable');
+6
View File
@@ -1,3 +1,9 @@
.project-type-label.label-outline {width: 50px; min-width: 50px;}
.project-type-label.label {overflow: unset !important; text-overflow: unset !important; white-space: unset !important;}
[lang^='en'] .project-name > .label-warning {width: 55px !important;}
.has-prefix {position: relative; display: flex; align-items: center;}
.has-prefix > span {flex: none;}
.has-prefix > a {padding-left: 5px;}
.has-suffix > a {max-width: calc(100% - 100px); padding-right: 5px; color: #0c60e1; display: inline-block; max-width: calc(100% - 50px);}
+1 -1
View File
@@ -67,7 +67,7 @@ function showEditCheckbox(show)
$tr.find('td:first').find('[name^="projectIdList"]').parent().remove();
}
});
if(show)
if(show && hasProject)
{
var tableFooter = "<div class='editCheckbox'><div class='checkbox-primary check-all'><input type='checkbox' id='checkAll' /><label>" + selectAll + "</label></div><div class='table-actions btn-toolbar'><button type='submit' class='btn'>" + edit + "</button></div></div>";
$('#programForm').attr('action', createLink('project', 'batchEdit', 'from=program'));
+2 -1
View File
@@ -15,6 +15,7 @@
<?php js::set('orderBy', $orderBy);?>
<?php js::set('edit', $lang->edit);?>
<?php js::set('selectAll', $lang->selectAll);?>
<?php js::set('hasProject', $hasProject);?>
<?php if($programType == 'bygrid'):?>
<style> #mainMenu{padding-left: 10px; padding-right: 10px;} </style>
<?php endif;?>
@@ -26,7 +27,7 @@
<?php echo html::a(inlink('browse', "status=$key&orderBy=$orderBy"), $label, '', "class='btn btn-link $active'");?>
<?php endforeach;?>
<?php echo html::checkbox('showClosed', array('1' => $lang->program->showClosed), '', $this->cookie->showClosed ? 'checked=checked' : '');?>
<?php if(common::hasPriv('project', 'batchEdit') and $programType != 'bygrid') echo html::checkbox('editProject', array('1' => $lang->project->edit), '', $this->cookie->editProject ? 'checked=checked' : '');?>
<?php if(common::hasPriv('project', 'batchEdit') and $programType != 'bygrid' and $hasProject === true) echo html::checkbox('editProject', array('1' => $lang->project->edit), '', $this->cookie->editProject ? 'checked=checked' : '');?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->user->search;?></a>
</div>
<div class='pull-right'>
+1 -1
View File
@@ -146,7 +146,7 @@
</tbody>
</table>
<div class='table-footer <?php if($status == 'bySearch') echo 'hide';?>'>
<div class="table-statistic"><?php echo $summary;?></div>
<div class="table-statistic">&nbsp;<?php echo $summary;?></div>
<?php if($status != 'bySearch') $pager->show('right', 'pagerjs');?>
</div>
</form>
+4 -7
View File
@@ -432,13 +432,9 @@ class project extends control
$this->executeHooks($projectID);
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $projectID));
if($this->app->tab == 'program')
if($this->app->tab != 'project' and $this->session->createProjectLocate)
{
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('program', 'browse')));
}
elseif($this->app->tab == 'doc')
{
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('doc', 'objectLibs', "type=project&objectID=$projectID")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->session->createProjectLocate));
}
else
{
@@ -454,7 +450,7 @@ class project extends control
}
}
if($this->app->tab == 'program') $this->loadModel('program')->setMenu($programID);
if($this->app->tab == 'program' and $programID) $this->loadModel('program')->setMenu($programID);
$this->session->set('projectModel', $model);
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
@@ -491,6 +487,7 @@ class project extends control
}
if($this->app->tab == 'doc') unset($this->lang->doc->menu->project['subMenu']);
if($this->app->tab == 'product' and isset($output['productID'])) $this->loadModel('product')->setMenu($output['productID']);
$topProgramID = $this->program->getTopByID($programID);
+6
View File
@@ -179,6 +179,9 @@ function loadBranches(product)
}
});
$("input[name='products[" + index + "]']").remove();
$("input[name='branch[" + index + "]']").remove();
loadPlans(product);
}
@@ -190,6 +193,9 @@ function loadPlans(product, branchID)
var branchID = typeof(branchID) == 'undefined' ? 0 : branchID;
var index = $(product).attr('id').replace('products', '');
$("input[name='products[" + index + "]']").remove();
$("input[name='branch[" + index + "]']").remove();
$.get(createLink('product', 'ajaxGetPlans', "productID=" + productID + '&branch=0,' + branchID + '&planID=0&fieldID&needCreate=&expired=' + (config.currentMethod == 'create' ? 'unexpired' : '') + '&param=skipParent'), function(data)
{
if(data)
+27 -11
View File
@@ -906,7 +906,7 @@ class projectModel extends model
* @access public
* @return array
*/
public function getPairsByModel($model = 'all', $programID = 0, $param = '', $append = '')
public function getPairsByModel($model = 'all', $programID = 0, $param = '', $append = '', $orderBy = 'order_asc')
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectPairs();
@@ -920,7 +920,7 @@ class projectModel extends model
->beginIF(strpos($param, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi()
->beginIF(!empty($append))->orWhere('id')->in($append)->fi()
->orderBy('id_desc')
->orderBy($orderBy)
->fetchAll();
$programIdList = array();
@@ -932,16 +932,29 @@ class projectModel extends model
$projectProgram[$project->id] = $programID;
}
$programs = $this->dao->select('id, name')->from(TABLE_PROGRAM)->where('id')->in($programIdList)->fetchPairs('id', 'name');
$pairs = array();
$programs = $this->dao->select('id, name')->from(TABLE_PROGRAM)->where('id')->in($programIdList)->orderBy($orderBy)->fetchPairs('id', 'name');
/* Sort by project order in the program list. */
$allProjects = array();
foreach($programs as $programID => $program) $allProjects[$programID] = array();
foreach($projects as $project)
{
$projectName = $project->name;
$programID = zget($projectProgram, $project->id, '');
if($programID != $project->id) $projectName = zget($programs, $programID, '') . ' / ' . $projectName;
$allProjects[$programID][] = $project;
}
$pairs[$project->id] = $projectName;
$pairs = array();
foreach($allProjects as $programID => $projects)
{
foreach($projects as $project)
{
$projectName = $project->name;
$programID = zget($projectProgram, $project->id, '');
if($programID != $project->id) $projectName = zget($programs, $programID, '') . ' / ' . $projectName;
$pairs[$project->id] = $projectName;
}
}
return $pairs;
@@ -956,9 +969,12 @@ class projectModel extends model
*/
public function getStoriesByProject($projectID = 0)
{
return $this->dao->select('*')->from(TABLE_PROJECTSTORY)
->beginIF($projectID)->where('project')->eq($projectID)->fi()
->fetchGroup('product', 'branch');
return $this->dao->select("t2.product, t2.branch, GROUP_CONCAT(t2.story) as storyIDList")->from(TABLE_STORY)->alias('t1')
->leftJoin(TABLE_PROJECTSTORY)->alias('t2')->on('t1.id=t2.story')
->where('t1.deleted')->eq(0)
->beginIF($projectID)->andWhere('t2.project')->eq($projectID)->fi()
->groupBy('product, branch')
->fetchGroup('product', 'branch');
}
/**
+3 -1
View File
@@ -42,7 +42,9 @@
<table class='table table-form'>
<tr>
<th class='w-120px'><?php echo $lang->project->parent;?></th>
<td><?php echo html::select('parent', $programList, $programID, "class='form-control chosen' onchange='setParentProgram(this.value)'");?></td>
<?php $disabled = $this->app->tab == 'product' ? 'disabled' : '';?>
<td><?php echo html::select('parent', $programList, $programID, "class='form-control chosen' onchange='setParentProgram(this.value)' $disabled");?></td>
<?php if($disabled) echo html::hidden('parent', $programID);?>
<td>
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->program->tips;?>"></icon>
</td>
+3 -3
View File
@@ -22,21 +22,21 @@
<div class='row'>
<div class='col-xs-4'>
<div class='project-type text-center'>
<?php echo html::a($this->createLink("project", "create", "model=scrum&programID=$programID&copyProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='scrum' src='{$config->webRoot}theme/default/images/main/scrum.png'>", '', "data-app='project' class='createButton'")?>
<?php echo html::a($this->createLink("project", "create", "model=scrum&programID=$programID&copyProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='scrum' src='{$config->webRoot}theme/default/images/main/scrum.png'>", '', "data-app='{$this->app->tab}' class='createButton'")?>
<h3><?php echo $lang->project->scrum; ?></h3>
<p><?php echo $lang->project->scrumTitle; ?></p>
</div>
</div>
<div class='col-xs-4'>
<div class='project-type text-center'>
<?php echo html::a($this->createLink("project", "create", "model=waterfall&programID=$programID&copyProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='waterfall' src='{$config->webRoot}theme/default/images/main/waterfall.png'>", '', "data-app='project' class='createButton'")?>
<?php echo html::a($this->createLink("project", "create", "model=waterfall&programID=$programID&copyProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='waterfall' src='{$config->webRoot}theme/default/images/main/waterfall.png'>", '', "data-app='{$this->app->tab}' class='createButton'")?>
<h3><?php echo $lang->project->waterfall; ?></h3>
<p><?php echo $lang->project->waterfallTitle; ?></p>
</div>
</div>
<div class='col-xs-4'>
<div class='project-type text-center'>
<?php echo html::a($this->createLink("project", "create", "model=kanban&programID=$programID&copyProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='kanban' src='{$config->webRoot}theme/default/images/main/kanban.png'>", '', "data-app='project' class='createButton'")?>
<?php echo html::a($this->createLink("project", "create", "model=kanban&programID=$programID&copyProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='kanban' src='{$config->webRoot}theme/default/images/main/kanban.png'>", '', "data-app='{$this->app->tab}' class='createButton'")?>
<h3><?php echo $lang->project->kanban;?></h3>
<p><?php echo $lang->project->kanbanTitle;?></p>
</div>
+1 -1
View File
@@ -1004,7 +1004,7 @@ class repo extends control
}
$this->dao->update(TABLE_REPO)->set('commits=commits + ' . $commitCount)->where('id')->eq($repoID)->exec();
echo ($type == 'batch' and $commitCount) ? $commitCount : 'finish';
echo $type == 'batch' ? $commitCount : 'finish';
}
/**
+1 -1
View File
@@ -57,7 +57,7 @@ class repoModel extends model
}
common::setMenuVars('devops', $repoID);
session_start();
if(!session_id()) session_start();
$this->session->set('repoID', $repoID);
session_write_close();
}
+1
View File
@@ -602,6 +602,7 @@ class story extends control
$this->view->branches = $branches;
/* When the user is product owner or add story in project or not set review, the default is not to review. */
$this->view->needReview = ($this->app->user->account == $product->PO || $executionID > 0 || $this->config->story->needReview == 0) ? 0 : 1;
$this->view->forceReview = $this->story->checkForceReview();
$this->view->executionID = $executionID;
$this->display();
+1 -1
View File
@@ -62,7 +62,7 @@
<th class='c-category'><?php echo $lang->story->category;?></th>
<th class='c-pri<?php echo zget($visibleFields, 'pri', ' hidden') . zget($requiredFields, 'pri', '', ' required');?>'><?php echo $lang->story->pri;?></th>
<th class='c-estimate<?php echo zget($visibleFields, 'estimate', ' hidden') . zget($requiredFields, 'estimate', '', ' required');?>'><?php echo $lang->story->estimate;?></th>
<th class='<?php echo zget($visibleFields, 'review', ' hidden');?>' style="width: 200px !important"><?php echo $lang->story->reviewedBy;?></th>
<th class='<?php echo zget($visibleFields, 'review', ' hidden');?><?php if($forceReview) echo ' required'?>' style="width: 200px !important"><?php echo $lang->story->reviewedBy;?></th>
<th class='c-keywords<?php echo zget($visibleFields, 'keywords', ' hidden') . zget($requiredFields, 'keywords', '', ' required');?>'><?php echo $lang->story->keywords;?></th>
<?php
$extendFields = $this->story->getFlowExtendFields();
+15
View File
@@ -26,4 +26,19 @@ $(document).ready(function()
inputFocusJump('down');
}
});
$('#customField').click(function()
{
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
{
var field = ',' + $(this).val() + ',';
var required = ',' + requiredFields + ',';
if(required.indexOf(field) >= 0) $(this).attr('disabled', 'disabled');
});
});
$('#formSettingForm .btn-primary').click(function()
{
$('#formSettingForm > .checkboxes > .checkbox-primary > input').removeAttr('disabled');
});
});
+15
View File
@@ -113,6 +113,21 @@ $(function()
});
});
}
$('#customField').click(function()
{
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
{
var field = ',' + $(this).val() + ',';
var required = ',' + requiredFields + ',';
if(required.indexOf(field) >= 0) $(this).attr('disabled', 'disabled');
});
});
$('#formSettingForm .btn-primary').click(function()
{
$('#formSettingForm > .checkboxes > .checkbox-primary > input').removeAttr('disabled');
});
});
$(document).on('click', '.chosen-with-drop', function(){oldValue = $(this).prev('select').val();})//Save old value.
+2
View File
@@ -220,6 +220,8 @@ $lang->testcase->resultList['blocked'] = 'Blocked';
$lang->testcase->buttonToList = 'Back';
$lang->testcase->whichLine = 'Line No.%s : ';
$lang->testcase->stepsEmpty = 'Step %s cannot be empty.';
$lang->testcase->errorEncode = 'No data. Please select right encoding and upload again!';
$lang->testcase->noFunction = 'Iconv and mb_convert_encoding are not found. You cannot convert the data to the encoding you want!';
$lang->testcase->noRequire = "Row %s has“%s ”which is a required field and it should not be blank.";
+2
View File
@@ -220,6 +220,8 @@ $lang->testcase->resultList['blocked'] = '阻塞';
$lang->testcase->buttonToList = '返回';
$lang->testcase->whichLine = '第%s行';
$lang->testcase->stepsEmpty = '步骤%s不能为空';
$lang->testcase->errorEncode = '无数据,请选择正确的编码重新上传!';
$lang->testcase->noFunction = '不存在iconv和mb_convert_encoding转码方法,不能将数据转成想要的编码!';
$lang->testcase->noRequire = "%s行的“%s”是必填字段,不能为空";
+35
View File
@@ -39,6 +39,17 @@ class testcaseModel extends model
*/
function create($bugID)
{
$steps = $this->post->steps;
$expects = $this->post->expects;
foreach($expects as $key => $value)
{
if(!empty($value) and empty($steps[$key]))
{
dao::$errors[] = sprintf($this->lang->testcase->stepsEmpty, $key);
return false;
}
}
$now = helper::now();
$status = $this->getStatus('create');
$case = fixer::input('post')
@@ -705,6 +716,17 @@ class testcaseModel extends model
*/
public function update($caseID, $testtasks = array())
{
$steps = $this->post->steps;
$expects = $this->post->expects;
foreach($expects as $key => $value)
{
if(!empty($value) and empty($steps[$key]))
{
dao::$errors[] = sprintf($this->lang->testcase->stepsEmpty, $key);
return false;
}
}
$now = helper::now();
$oldCase = $this->getById($caseID);
@@ -1203,6 +1225,19 @@ class testcaseModel extends model
$branch = (int)$branch;
$data = fixer::input('post')->get();
$steps = $data->desc;
foreach($data->expect as $key => $expects)
{
foreach($expects as $exportID => $value)
{
if(!empty($value) and (!isset($steps[$key][$exportID]) or empty($steps[$key][$exportID])))
{
dao::$errors = sprintf($this->lang->testcase->whichLine, $key) . sprintf($this->lang->testcase->stepsEmpty, $exportID);
return false;
}
}
}
if(!empty($_POST['id']))
{
$oldSteps = $this->dao->select('t2.*')->from(TABLE_CASE)->alias('t1')
@@ -14,6 +14,7 @@
<?php js::set('testcaseBatchCreateNum', $config->testcase->batchCreate);?>
<?php js::set('productID', $productID);?>
<?php js::set('branch', $branch);?>
<?php js::set('requiredFields', $config->testcase->create->requiredFields)?>
<div id="mainContent" class="main-content fade">
<div class="main-header">
<h2>
+1
View File
@@ -16,6 +16,7 @@
<?php js::set('testtasks', $testtasks);?>
<?php js::set('confirmUnlinkTesttask', $lang->testcase->confirmUnlinkTesttask);?>
<?php js::set('isLibCase', $isLibCase);?>
<?php js::set('requiredFields', $config->testcase->edit->requiredFields)?>
<div id="mainContent" class="main-content">
<div class="main-header">
<h2><?php echo $lang->testcase->common . $lang->colon . $lang->testcase->batchEdit;?></h2>
+2 -2
View File
@@ -298,7 +298,7 @@ class upgrade extends control
}
/* When upgrading historical data as a project, handle products that are not linked with the project. */
if(!empty($singleProducts)) $this->upgrade->computeProductAcl($singleProducts, $programID);
if(!empty($singleProducts)) $this->upgrade->computeProductAcl($singleProducts, $programID, $lineID);
/* Process unlinked sprint and product. */
foreach($linkedProducts as $productID => $product)
@@ -353,7 +353,7 @@ class upgrade extends control
}
/* When upgrading historical data as a project, handle products that are not linked with the project. */
if(!empty($singleProducts)) $this->upgrade->computeProductAcl($singleProducts, $programID);
if(!empty($singleProducts)) $this->upgrade->computeProductAcl($singleProducts, $programID, $lineID);
}
elseif($type == 'sprint')
{
+4 -2
View File
@@ -4802,7 +4802,7 @@ class upgradeModel extends model
$this->dao->update(TABLE_RELEASE)->set('project')->eq($projectID)->where('product')->in($productIdList)->exec();
/* Compute product acl. */
$this->computeProductAcl($productIdList, $programID);
$this->computeProductAcl($productIdList, $programID, $lineID);
/* No project is created when there are no sprints. */
if(!$sprintIdList) return;
@@ -4941,10 +4941,11 @@ class upgradeModel extends model
*
* @param array $productIdList
* @param int $programID
* @param int $lineID
* @access public
* @return void
*/
public function computeProductAcl($productIdList = array(), $programID = 0)
public function computeProductAcl($productIdList = array(), $programID = 0, $lineID = 0)
{
/* Compute product acl. */
$products = $this->dao->select('id,program,acl')->from(TABLE_PRODUCT)->where('id')->in($productIdList)->fetchAll();
@@ -4955,6 +4956,7 @@ class upgradeModel extends model
$data = new stdclass();
$data->program = $programID;
$data->acl = $product->acl == 'custom' ? 'private' : $product->acl;
$data->line = $lineID;
$this->dao->update(TABLE_PRODUCT)->data($data)->where('id')->eq($product->id)->exec();
}
+33
View File
@@ -2045,4 +2045,37 @@ class bugTest
return $array;
}
}
/**
* Test get bugs of assigned by me.
*
* @param string $productIDList
* @param string $moduleIDList
* @access public
* @return string
*/
public function getByAssignedbymeTest($productIDList, $moduleIDList)
{
global $tester;
$executions = $tester->loadModel('execution')->getPairs('0', 'all', 'empty|withdelete');
$bugs = $this->objectModel->getByAssignedbyme($productIDList, 'all', $moduleIDList, $executions, 'id_desc', null, 0);
$title = '';
foreach($bugs as $bug)
{
$title .= ',' . $bug->title;
}
$title = trim($title, ',');
$title = str_replace("'", '', $title);
if(dao::isError())
{
return dao::getError();
}
else
{
return $title;
}
}
}
+4 -2
View File
@@ -519,10 +519,11 @@ class kanbanTest
* @param int $kanbanID
* @param string $fromType
* @param int $archived
* @param int $regionID
* @access public
* @return string
*/
public function getImportedCardsTest($kanbanID, $fromType, $archived = 0)
public function getImportedCardsTest($kanbanID, $fromType, $archived = 0, $regionID = 0)
{
global $tester;
$cards = $tester->dao->select('*')->from(TABLE_KANBANCARD)
@@ -530,9 +531,10 @@ class kanbanTest
->andWhere('kanban')->eq($kanbanID)
->andWhere('archived')->eq($archived)
->andWhere('fromID')->eq(0)
->beginIF($regionID)->andWhere('region')->eq($regionID)->fi()
->fetchAll('id');
$objects = $this->objectModel->getImportedCards($kanbanID, $cards, $fromType, $archived);
$objects = $this->objectModel->getImportedCards($kanbanID, $cards, $fromType, $archived, $regionID);
if(dao::isError()) return dao::getError();
+32
View File
@@ -82,4 +82,36 @@ class myTest
return $objects;
}
/**
* Function getAssignedByMe test by my
*
* @param string $account
* @param int $limit
* @param int $pager
* @param string $orderBy
* @param int $projectID
* @param string $objectType
* @access public
* @return int
*/
public function getAssignedByMeTest($account, $limit, $pager, $orderBy, $projectID, $objectType)
{
global $tester;
$recTotal = 0;
$recPerPage = 20;
$pageID = 0;
$tester->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$actionID = $tester->loadModel('action')->create('task', 6, 'assigned', '', '', 'admin', '');
$actionID = $tester->loadModel('action')->create('bug', 6, 'assigned', '', '', 'admin', '');
$actionID = $tester->loadModel('action')->create('story', 5, 'assigned', '', '', 'admin', '');
$objects = $this->objectModel->getAssignedByMe($account, $limit, $pager, $orderBy, $projectID, $objectType);
if(dao::isError()) return dao::getError();
return count($objects);
}
}
+22
View File
@@ -179,6 +179,28 @@ class productPlan
return $productplans;
}
/**
* Get top plan pairs
*
* @param int $productID
* @param int $branch
* @param int $exclude
* @access public
* @return array
*/
public function getTopPlanPairsTest($param)
{
$productID = $param['productID'];
$branch = $param['branch'];
$exclude = $param['exclude'];
$planPairs = $this->productplan->getTopPlanPairs($productID, $branch, $exclude);
if(dao::isError()) return dao::getError();
return $planPairs;
}
/**
* Create
*
+103 -77
View File
@@ -5,13 +5,13 @@ class storyTest
{
global $tester;
$this->objectModel = $tester->loadModel('story');
}
}
/**
* Test get by id.
*
* @param int $storyID
* @param int $version
*
* @param int $storyID
* @param int $version
* @access public
* @return void
*/
@@ -26,9 +26,9 @@ class storyTest
/**
* Test get by list.
*
* @param int $storyIdList
* @param string $type
*
* @param int $storyIdList
* @param string $type
* @access public
* @return void
*/
@@ -43,9 +43,9 @@ class storyTest
/**
* Test get test stories.
*
* @param array $storyIdList
* @param int $executionID
*
* @param array $storyIdList
* @param int $executionID
* @access public
* @return void
*/
@@ -60,8 +60,8 @@ class storyTest
/**
* Test get story specs.
*
* @param array $storyIdList
*
* @param array $storyIdList
* @access public
* @return void
*/
@@ -76,7 +76,7 @@ class storyTest
/**
* Test get affected scope.
*
*
* @param int $storyID
* @access public
* @return void
@@ -84,7 +84,7 @@ class storyTest
public function getAffectedScopeTest($storyID)
{
global $tester;
$story = $tester->loadModel('story')->getById($storyID);
$story = $tester->loadModel('story')->getById($storyID);
$scope = $this->objectModel->getAffectedScope($story);
if(dao::isError()) return dao::getError();
@@ -94,8 +94,8 @@ class storyTest
/**
* Test get requierements.
*
* @param int $productID
*
* @param int $productID
* @access public
* @return void
*/
@@ -110,11 +110,11 @@ class storyTest
/**
* Test create story.
*
* @param int $executionID
* @param int $bugID
* @param string $from
* @param string $extra
*
* @param int $executionID
* @param int $bugID
* @param string $from
* @param string $extra
* @access public
* @return void
*/
@@ -128,14 +128,14 @@ class storyTest
global $tester;
$storyID = $result['id'];
return $tester->loadModel('story')->getById($storyID);
return $tester->loadModel('story')->getById($storyID);
}
/**
* Test create story from gitlab issue.
*
* @param int $story
* @param int $executionID
*
* @param int $story
* @param int $executionID
* @access public
* @return void
*/
@@ -146,15 +146,15 @@ class storyTest
if(dao::isError()) return dao::getError();
global $tester;
return $tester->loadModel('story')->getById($storyID);
return $tester->loadModel('story')->getById($storyID);
}
/**
* Test batch create stories.
*
* @param int $productID
* @param int $branch
* @param string $type
*
* @param int $productID
* @param int $branch
* @param string $type
* @param array $params
* @access public
* @return void
@@ -176,8 +176,8 @@ class storyTest
/**
* Test change story.
*
* @param int $storyID
*
* @param int $storyID
* @param array $params
* @access public
* @return void
@@ -196,8 +196,8 @@ class storyTest
/**
* Test update story.
*
* @param int $storyID
*
* @param int $storyID
* @param array $params
* @access public
* @return void
@@ -215,10 +215,10 @@ class storyTest
/**
* Test update story order of plan.
*
* @param int $storyID
* @param string $planIDList
* @param string $oldPlanIDList
*
* @param int $storyID
* @param string $planIDList
* @param string $oldPlanIDList
* @access public
* @return void
*/
@@ -234,8 +234,8 @@ class storyTest
/**
* Test compute estimate.
*
* @param int $storyID
*
* @param int $storyID
* @access public
* @return void
*/
@@ -250,7 +250,7 @@ class storyTest
/**
* Test batch update stories.
*
*
* @access public
* @return void
*/
@@ -268,8 +268,8 @@ class storyTest
/**
* Test review story.
*
* @param int $storyID
*
* @param int $storyID
* @param array $params
* @access public
* @return void
@@ -287,10 +287,10 @@ class storyTest
/**
* Test batch review.
*
* @param int $storyIdList
* @param int $result
* @param int $reason
*
* @param int $storyIdList
* @param int $result
* @param int $reason
* @access public
* @return void
*/
@@ -306,9 +306,9 @@ class storyTest
/**
* Test story subdivide.
*
* @param int $storyID
* @param array $stories
*
* @param int $storyID
* @param array $stories
* @access public
* @return void
*/
@@ -331,8 +331,8 @@ class storyTest
/**
* Test close a story.
*
* @param int $storyID
*
* @param int $storyID
* @param array $params
* @access public
* @return void
@@ -350,8 +350,8 @@ class storyTest
/**
* Test batch close story.
*
* @param array $params
*
* @param array $params
* @access public
* @return void
*/
@@ -369,9 +369,9 @@ class storyTest
/**
* Test batch change story module.
*
* @param int $storyIdList
* @param int $moduleID
*
* @param int $storyIdList
* @param int $moduleID
* @access public
* @return void
*/
@@ -387,10 +387,10 @@ class storyTest
/**
* Test batch change story plan.
*
* @param arary $storyIdList
* @param int $planID
* @param int $oldPlanID
*
* @param arary $storyIdList
* @param int $planID
* @param int $oldPlanID
* @access public
* @return void
*/
@@ -406,11 +406,11 @@ class storyTest
/**
* Test batch change story branch.
*
* @param arary $storyIdList
* @param int $branchID
* @param string $confirm
* @param array $plans
*
* @param arary $storyIdList
* @param int $branchID
* @param string $confirm
* @param array $plans
* @access public
* @return void
*/
@@ -426,9 +426,9 @@ class storyTest
/**
* Test batch change stage.
*
* @param arrau $storyIdList
* @param string $stage
*
* @param arrau $storyIdList
* @param string $stage
* @access public
* @return void
*/
@@ -444,9 +444,9 @@ class storyTest
/**
* Test story batch to task.
*
* @param int $executionID
* @param int $projectID
*
* @param int $executionID
* @param int $projectID
* @param array $params
* @access public
* @return void
@@ -465,8 +465,8 @@ class storyTest
/**
* Test assign a story.
*
* @param int $storyID
*
* @param int $storyID
* @param string $assignedTo
* @access public
* @return void
@@ -484,8 +484,8 @@ class storyTest
/**
* Test batch assign story.
*
* @param array $params
*
* @param array $params
* @access public
* @return void
*/
@@ -500,4 +500,30 @@ class storyTest
$storyIdList = array_keys($changes);
return $this->objectModel->getByList($storyIdList);
}
/**
* Test get stories by assignedBy.
*
* @param int $productID
* @param int $branch
* @access public
* @return string
*/
public function getByAssignedByTest($productID, $branch)
{
global $tester;
$stories = $this->objectModel->getByAssignedBy($productID, $branch, $modules = array(), $account = $tester->app->user->account, $type = 'story', $orderBy = '', $pager = null);
$title = '';
foreach($stories as $story)
{
$title .= ',' . $story->title;
}
$title = trim($title, ',');
$title = str_replace("'", '', $title);
if(dao::isError()) return dao::getError();
return $title;
}
}
+11
View File
@@ -932,4 +932,15 @@ class userTest
{
return $this->objectModel->getVisionList();
}
/**
* Get users who have authority to create stories.
*
* @access public
* @return array
*/
public function getCanCreateStoryUsersTest()
{
return $this->objectModel->getCanCreateStoryUsers();
}
}
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/bug.class.php';
su('admin');
/**
title=bugModel->getByAssignedbyme();
cid=1
pid=1
查询产品1 2 3 不存在的产品10001 与模块1821, 1825, 1831 不存在的模块1000001下由我指派的bug >> 0
查询产品1 2 3 不存在的产品10001 与模块1821, 1825下由我指派的bug >> 0
查询产品1 2 3 不存在的产品10001 与不存在的模块1000001下由我指派的bug >> 0
查询产品1 3与模块1821, 1825, 1831 不存在的模块1000001下由我指派的bug >> 0
查询产品1 3与模块1821, 1825下由我指派的bug >> 0
查询产品1 3与模块不存在的模块1000001下由我指派的bug >> 0
查询不存在的产品10001 与模块1821, 1825, 1831 不存在的模块1000001下由我指派的bug >> 0
查询不存在的产品10001 与模块1821, 1825下由我指派的bug >> 0
查询不存在的产品10001 与不存在的模块1000001下由我指派的bug >> 0
*/
$productIDList = array('1,2,3,1000001', '1,3', '1000001');
$moduleIDList = array('1821,1825,1831,1000001', '1821, 1825', '1000001');
$bug=new bugTest();
r($bug->getByAssignedbymeTest($productIDList[0], $moduleIDList[0])) && p('title') && e('0'); // 查询产品1 2 3 不存在的产品10001 与模块1821, 1825, 1831 不存在的模块1000001下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[0], $moduleIDList[1])) && p('title') && e('0'); // 查询产品1 2 3 不存在的产品10001 与模块1821, 1825下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[0], $moduleIDList[2])) && p('title') && e('0'); // 查询产品1 2 3 不存在的产品10001 与不存在的模块1000001下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[1], $moduleIDList[0])) && p('title') && e('0'); // 查询产品1 3与模块1821, 1825, 1831 不存在的模块1000001下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[1], $moduleIDList[1])) && p('title') && e('0'); // 查询产品1 3与模块1821, 1825下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[1], $moduleIDList[2])) && p('title') && e('0'); // 查询产品1 3与模块不存在的模块1000001下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[2], $moduleIDList[0])) && p('title') && e('0'); // 查询不存在的产品10001 与模块1821, 1825, 1831 不存在的模块1000001下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[2], $moduleIDList[1])) && p('title') && e('0'); // 查询不存在的产品10001 与模块1821, 1825下由我指派的bug
r($bug->getByAssignedbymeTest($productIDList[2], $moduleIDList[2])) && p('title') && e('0'); // 查询不存在的产品10001 与不存在的模块1000001下由我指派的bug
+2
View File
@@ -27,6 +27,7 @@ pid=1
查看看板25的普通卡片和build卡片 >> ,193,194,195,196,197,198,199,200,993,994,995,996,997,998,999,1000
查看看板25的普通卡片和productplan片 >> ,193,194,195,196,197,198,199,200
查看看板1已归档的普通卡片和productplan卡片 >> ,6,7,8,801,802,803,804,805,806,807,808
查看区域ID=1中看板1已归档的普通卡片和productplan卡片 >> ,6,7,8,801,802,803,804,805,806,807,808
*/
@@ -55,4 +56,5 @@ r($kanban->getImportedCardstest($kanbanIDList[7], $fromType[0])) && p() && e(',1
global $tester;
$tester->dao->update(TABLE_KANBANCARD)->set('archived')->eq(1)->where('id')->gt('5')->exec();
r($kanban->getImportedCardsTest($kanbanIDList[0], $fromType[0], $archived)) && p() && e(',6,7,8,801,802,803,804,805,806,807,808'); // 查看看板1已归档的普通卡片和productplan卡片
r($kanban->getImportedCardsTest($kanbanIDList[0], $fromType[0], $archived, 1)) && p() && e(',6,7,8,801,802,803,804,805,806,807,808'); // 查看区域ID=1中看板1已归档的普通卡片和productplan卡片
$tester->dao->update(TABLE_KANBANCARD)->set('archived')->eq(0)->where('id')->gt('5')->exec();
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/my.class.php';
su('admin');
/**
title=测试 myModel->getAssignedByMe();
cid=1
pid=1
当插入一条action为admin指派了task的动态时,查询结果为1条数据 >> 1
当插入一条action为admin指派了bug的动态时,查询结果为1条数据 >> 1
当插入一条action为admin指派了需求的动态时,查询结果为1条数据 >> 1
*/
$my = new myTest();
$task = array('admin', 0, '', 'id_desc', 0, 'task');
$bug = array('admin', 0, '', 'id_desc', 0, 'bug');
$story = array('admin', 0, '', 'id_desc', 0, 'story');
r($my->getAssignedByMeTest($task[0], $task[1], $task[2], $task[3], $task[4], $task[5])) && p() && e('1'); // 当插入一条action为admin指派了task的动态时,查询结果为1条数据
r($my->getAssignedByMeTest($bug[0], $bug[1], $bug[2], $bug[3], $bug[4], $bug[5])) && p() && e('1'); // 当插入一条action为admin指派了bug的动态时,查询结果为1条数据
r($my->getAssignedByMeTest($story[0], $story[1], $story[2], $story[3], $story[4], $story[5])) && p() && e('1'); // 当插入一条action为admin指派了需求的动态时,查询结果为1条数据
system("./ztest init");
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/productplan.class.php';
$plan = new productPlan('admin');
$param = array();
$param[0] = array('productID' => 1, 'branch' => '', 'exclude' => '');
$param[1] = array('productID' => 1, 'branch' => '', 'exclude' => 1);
$param[2] = array('productID' => 41, 'branch' => 1, 'exclude' => '');
$param[3] = array('productID' => 41, 'branch' => 2, 'exclude' => '');
r($plan->getTopPlanPairsTest($param[0])) && p('1,2') && e('1.0,1.1'); //测试获取正常产品的顶级计划
r($plan->getTopPlanPairsTest($param[1])) && p('1,2') && e(',1.1'); //测试获取排除1.0计划的正常产品的顶级计划
r($plan->getTopPlanPairsTest($param[2])) && p('31') && e('1.0'); //测试获取分支1计划的正常产品的顶级计划
r($plan->getTopPlanPairsTest($param[3])) && p('32') && e('1.1'); //测试获取分支2计划的正常产品的顶级计划
?>
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/story.class.php';
su('admin');
/**
title=storyModel->getByAssignedbyme();
cid=1
pid=1
查看产品 1 由我指派的需求 >> 0
查看产品 2 由我指派的需求 >> 0
查看产品 3 由我指派的需求 >> 0
查看产品 4 由我指派的需求 >> 0
查看产品 5 由我指派的需求 >> 0
*/
$productIDList = array(1, 2, 3, 4 ,5);
$branch = 'all';
$story=new storyTest();
r($story->getByAssignedByTest($productIDList[0], $branch)) && p() && e('0'); // 查看产品 1 由我指派的需求
r($story->getByAssignedByTest($productIDList[1], $branch)) && p() && e('0'); // 查看产品 2 由我指派的需求
r($story->getByAssignedByTest($productIDList[2], $branch)) && p() && e('0'); // 查看产品 3 由我指派的需求
r($story->getByAssignedByTest($productIDList[3], $branch)) && p() && e('0'); // 查看产品 4 由我指派的需求
r($story->getByAssignedByTest($productIDList[4], $branch)) && p() && e('0'); // 查看产品 5 由我指派的需求
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/user.class.php';
su('admin');
/**
title=测试 userModel->getCanCreateStoryUsers();
cid=1
pid=1
查找系统中有权限创建、批量创建需求的用户 >> A:admin;T:产品主管48
*/
$user = new userTest();
r($user->getCanCreateStoryUsersTest()) && p('admin;td48') && e('A:admin;T:产品主管48'); //查找系统中有权限创建、批量创建需求的用户
+1 -1
View File
@@ -18,7 +18,7 @@ pid=1
*/
$user = new userTest();
a($user->getListTest());die;
r($user->getListTest()) && p('1:realname') && e('开发1'); //查找系统中第二个未删除的、内部用户真实姓名,根据account正序排
r($user->getListTest()) && p('998:realname') && e('测试99'); //查找系统中未删除的、根据account正序排的最后一个用户的姓名
r($user->getListTest(true)) && p() && e('999'); //查找系统中所有未删除的、内部用户的数量