Merge branch 'liyuchun_65983' into 'zenops_44'

Liyuchun 65983

See merge request easycorp/zentaopms!5147
This commit is contained in:
孙广明
2022-08-26 06:35:25 +00:00
35 changed files with 872 additions and 148 deletions
+1
View File
@@ -934,6 +934,7 @@ class bug extends control
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, 'all', '');
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('bug', $bugID);
$this->view->product = $product;
$this->view->linkCommits = $this->loadModel('repo')->getCommitsByObject($bugID, 'bug');
$this->view->projects = array('' => '') + $projects;
+1
View File
@@ -176,6 +176,7 @@ $lang->bug->labelPostponed = 'Postponed';
$lang->bug->changed = 'Changed';
$lang->bug->storyChanged = 'Story Changed';
$lang->bug->linkMR = 'Related MRs';
$lang->bug->linkCommit = 'Related Commits';
$lang->bug->duplicateTip = 'Please enter keyword search';
/* Page tags. */
+1
View File
@@ -176,6 +176,7 @@ $lang->bug->labelPostponed = 'Postponed';
$lang->bug->changed = 'Changed';
$lang->bug->storyChanged = 'Story Changed';
$lang->bug->linkMR = 'Related MRs';
$lang->bug->linkCommit = 'Related Commits';
$lang->bug->duplicateTip = 'Please enter keyword search';
/* Page tags. */
+1
View File
@@ -176,6 +176,7 @@ $lang->bug->labelPostponed = 'Postponed';
$lang->bug->changed = 'Changed';
$lang->bug->storyChanged = 'Story Changed';
$lang->bug->linkMR = 'Related MRs';
$lang->bug->linkCommit = 'Related Commits';
$lang->bug->duplicateTip = 'Please enter keyword search';
/* Page tags. */
+2
View File
@@ -172,6 +172,8 @@ $lang->bug->legendComment = 'Ghi chú';
$lang->bug->legendLife = 'Toàn bộ';
$lang->bug->legendMisc = 'Khác';
$lang->bug->legendRelated = 'Thông tin liên quan';
$lang->bug->linkMRs = 'Related MRs';
$lang->bug->linkCommit = 'Related Commits';
/* Button. */
$lang->bug->buttonConfirm = 'Xác nhận';
+1
View File
@@ -176,6 +176,7 @@ $lang->bug->labelPostponed = '被延期';
$lang->bug->changed = '已变动';
$lang->bug->storyChanged = '需求变动';
$lang->bug->linkMR = '相关合并请求';
$lang->bug->linkCommit = '相关代码版本';
$lang->bug->duplicateTip = '请输入关键字';
/* 页面标签。*/
+13
View File
@@ -433,6 +433,19 @@
?>
</td>
</tr>
<tr>
<th><?php echo $lang->bug->linkCommit;?></th>
<td>
<?php
$canViewRevision = common::hasPriv('repo', 'revision');
foreach($linkCommits as $commit)
{
$revision = substr($commit->revision, 0, 10);
echo ($canViewRevision ? html::a($this->createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}"), "$revision {$commit->comment}") : "$revisioin {$commit->comment}") . '<br />';
}
?>
</td>
</tr>
</tbody>
</table>
</div>
+14 -1
View File
@@ -189,7 +189,20 @@ class gitModel extends model
' task:' . join(' ', $objects['tasks']) .
' bug:' . join(',', $objects['bugs']));
if($lastVersion != $version) $this->repo->saveAction2PMS($objects, $log, $this->repoRoot, $repo->encoding, 'git', $accountPairs);
if($lastVersion != $version)
{
$this->repo->saveAction2PMS($objects, $log, $this->repoRoot, $repo->encoding, 'git', $accountPairs);
/* Objects link commit. */
foreach($objects as $objectType => $objectIDs)
{
$objectTypeMap = array('stories' => 'story', 'bugs' => 'bug', 'tasks' => 'task');
if(empty($objectIDs) or !isset($objectTypeMap[$objectType])) continue;
$this->post->$objectType = $objectIDs;
$this->repo->link($repo->id, $log->revision, $objectTypeMap[$objectType]);
}
}
}
else
{
+268
View File
@@ -1004,6 +1004,274 @@ class repo extends control
$this->display();
}
/**
* Link story to commit.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function linkStory($repoID, $revision, $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
if(!empty($_POST['stories']))
{
$this->repo->link($repoID, $revision, 'story');
if(dao::isError()) return print(js::error(dao::getError()));
return print(js::closeModal('parent', '', "parent[1].getRelation('$revision')"));
}
$this->loadModel('story');
$this->app->loadLang('productplan');
$repo = $this->repo->getRepoByID($repoID);
$product = $this->loadModel('product')->getById($repo->product);
$modules = $this->loadModel('tree')->getOptionMenu($repo->product, 'story');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build search form. */
unset($this->lang->story->statusList['closed']);
$storyStatusList = $this->lang->story->statusList;
$queryID = $browseType == 'bySearch' ? (int)$param : 0;
unset($this->config->product->search['fields']['product']);
$this->config->product->search['actionURL'] = $this->createLink('repo', 'linkStory', "repoID=$repoID&revision=$revision&browseType=bySearch&queryID=myQueryID");
$this->config->product->search['queryID'] = $queryID;
$this->config->product->search['style'] = 'simple';
$this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($repo->product => $repo->product));
$this->config->product->search['params']['module']['values'] = $modules;
$this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $storyStatusList);
if($product->type == 'normal')
{
unset($this->config->product->search['fields']['branch']);
unset($this->config->product->search['params']['branch']);
}
else
{
$this->config->product->search['fields']['branch'] = $this->lang->product->branch;
$this->config->product->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
}
session_start();
$this->loadModel('search')->setSearchParams($this->config->product->search);
session_write_close();
$linkedStories = $this->repo->getRelationByCommit($repoID, $revision, 'story');
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch($product->id, 0, $queryID, 'id', '', 'story', array_keys($linkedStories), $pager);
}
else
{
$allStories = $this->story->getProductStories($product->id, 0, '0', 'draft,active,changed', 'story', 'id_desc', false, array_keys($linkedStories), $pager);
}
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->allStories = $allStories;
$this->view->product = $product;
$this->view->repoID = $repoID;
$this->view->revision = $revision;
$this->view->browseType = $browseType;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->display();
}
/**
* Link bug to commit.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function linkBug($repoID, $revision = '', $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
if(!empty($_POST['bugs']))
{
$this->repo->link($repoID, $revision, 'bug');
if(dao::isError()) return print(js::error(dao::getError()));
return print(js::closeModal('parent', '', "parent[1].getRelation('$revision')"));
}
$this->loadModel('bug');
$this->app->loadLang('productplan');
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$repo = $this->repo->getRepoByID($repoID);
$product = $this->loadModel('product')->getById($repo->product);
$modules = $this->loadModel('tree')->getOptionMenu($product->id, 'bug');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build search form. */
$this->config->bug->search['actionURL'] = $this->createLink('repo', 'linkBug', "repoID=$repoID&revision=$revision&browseType=bySearch&queryID=myQueryID");
$this->config->bug->search['queryID'] = $queryID;
$this->config->bug->search['style'] = 'simple';
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($product->id => $product->id));
$this->config->bug->search['params']['module']['values'] = $modules;
$this->config->bug->search['params']['execution']['values'] = $this->product->getExecutionPairsByProduct($product->id);
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($product->id, $branch = 'all', $params = '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->loadModel('build')->getBuildPairs($product->id, $branch = 'all', $params = '');
unset($this->config->bug->search['fields']['product']);
if($product->type == 'normal')
{
unset($this->config->bug->search['fields']['branch']);
unset($this->config->bug->search['params']['branch']);
}
else
{
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
}
session_start();
$this->loadModel('search')->setSearchParams($this->config->bug->search);
session_write_close();
$linkedBugs = $this->repo->getRelationByCommit($repoID, $revision, 'bug');
if($browseType == 'bySearch')
{
$allBugs = $this->bug->getBySearch($product->id, 0, $queryID, 'id_desc', array_keys($linkedBugs), $pager);
}
else
{
$allBugs = $this->bug->getActiveBugs($product->id, 0, '0', array_keys($linkedBugs), $pager);
}
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->allBugs = $allBugs;
$this->view->product = $product;
$this->view->repoID = $repoID;
$this->view->revision = $revision;
$this->view->browseType = $browseType;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->display();
}
/**
* Link task to commit.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function linkTask($repoID, $revision = '', $browseType = 'unclosed', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
if(!empty($_POST['tasks']))
{
$this->repo->link($repoID, $revision, 'task');
if(dao::isError()) return print(js::error(dao::getError()));
return print(js::closeModal('parent', '', "parent[1].getRelation('$revision')"));
}
$this->loadModel('execution');
$this->loadModel('product');
$this->app->loadLang('task');
/* Set browse type. */
$browseType = strtolower($browseType);
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$repo = $this->repo->getRepoByID($repoID);
$product = $this->loadModel('product')->getById($repo->product);
$modules = $this->loadModel('tree')->getOptionMenu($product->id, $viewType = 'task');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build search form. */
$this->config->execution->search['actionURL'] = $this->createLink('repo', 'linkTask', "repoID=$repoID&revision=$revision&browseType=bySearch&queryID=myQueryID", '', true);
$this->config->execution->search['queryID'] = $queryID;
$this->config->execution->search['style'] = 'simple';
$this->config->execution->search['params']['module']['values'] = $modules;
$this->config->execution->search['params']['execution']['values'] = $this->product->getExecutionPairsByProduct($product->id);
/* Get executions by product. */
$productExecutions = $this->product->getExecutionPairsByProduct($product->id);
$productExecutionIDs = array_filter(array_keys($productExecutions));
$this->config->execution->search['params']['execution']['values'] = array_filter($productExecutions);
session_start();
$this->loadModel('search')->setSearchParams($this->config->execution->search);
session_write_close();
/* Get tasks by executions. */
$allTasks = array();
foreach($productExecutionIDs as $productExecutionID)
{
$tasks = $this->execution->getTasks(0, $productExecutionID, array(), $browseType, $queryID, 0, $orderBy, null);
$allTasks = array_merge($tasks, $allTasks);
}
/* Filter linked tasks. */
$linkedTasks = $this->repo->getRelationByCommit($repoID, $revision, 'task');
$linkedTaskIDs = array_keys($linkedTasks);
foreach($allTasks as $key => $task)
{
if(in_array($task->id, $linkedTaskIDs)) unset($allTasks[$key]);
}
/* Page the records. */
$pager->setRecTotal(count($allTasks));
$pager->setPageTotal();
if($pager->pageID > $pager->pageTotal) $pager->setPageID($pager->pageTotal);
$count = 1;
$limitMin = ($pager->pageID - 1) * $pager->recPerPage;
$limitMax = $pager->pageID * $pager->recPerPage;
foreach($allTasks as $key => $task)
{
if($count <= $limitMin or $count > $limitMax) unset($allTasks[$key]);
$count ++;
}
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->allTasks = $allTasks;
$this->view->product = $product;
$this->view->repoID = $repoID;
$this->view->revision = $revision;
$this->view->browseType = $browseType;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->display();
}
/**
* Ajax sync comment.
*
+13
View File
@@ -115,3 +115,16 @@ $(function()
}
})
});
/**
* Load link object page.
*
* @param string $link
* @access public
* @return void
*/
function loadLinkPage(link)
{
$('#linkObject').attr('href', link);
$('#linkObject').click()
}
+5
View File
@@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download Zip file';
$lang->repo->sshClone = 'Clone with SSH';
$lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->submit = 'Submit';
$lang->repo->cancel = 'Cancel';
@@ -104,6 +106,9 @@ $lang->repo->job = 'Job';
$lang->repo->fileServerUrl = 'File Server Url';
$lang->repo->fileServerAccount = 'File Server Account';
$lang->repo->fileServerPassword = 'File Server Password';
$lang->repo->linkStory = 'Link ' . $lang->SRCommon;
$lang->repo->linkBug = 'Link Bug';
$lang->repo->linkTask = 'Link Task';
$lang->repo->title = 'Title';
$lang->repo->status = 'Status';
+5
View File
@@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download compressed package';
$lang->repo->sshClone = 'Clone with SSH';
$lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->submit = 'Submit';
$lang->repo->cancel = 'Cancel';
@@ -104,6 +106,9 @@ $lang->repo->job = 'Job';
$lang->repo->fileServerUrl = 'File Server Url';
$lang->repo->fileServerAccount = 'File Server Account';
$lang->repo->fileServerPassword = 'File Server Password';
$lang->repo->linkStory = 'Link ' . $lang->SRCommon;
$lang->repo->linkBug = 'Link Bug';
$lang->repo->linkTask = 'Link Task';
$lang->repo->title = 'Title';
$lang->repo->status = 'Status';
+5
View File
@@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download compressed package';
$lang->repo->sshClone = 'Clone with SSH';
$lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->submit = 'Soumettre';
$lang->repo->cancel = 'Annuler';
@@ -104,6 +106,9 @@ $lang->repo->job = 'Job';
$lang->repo->fileServerUrl = 'File Server Url';
$lang->repo->fileServerAccount = 'File Server Account';
$lang->repo->fileServerPassword = 'File Server Password';
$lang->repo->linkStory = 'Link ' . $lang->SRCommon;
$lang->repo->linkBug = 'Link Bug';
$lang->repo->linkTask = 'Link Task';
$lang->repo->title = 'Titre';
$lang->repo->status = 'Statut';
+5
View File
@@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download compressed package';
$lang->repo->sshClone = 'Clone with SSH';
$lang->repo->httpClone = 'Clone with HTTP';
$lang->repo->cloneUrl = 'Clone URL';
$lang->repo->linkTask = 'Link Task';
$lang->repo->unlinkedTasks = 'Unlinked Tasks';
$lang->repo->submit = 'Gửi';
$lang->repo->cancel = 'Hủy';
@@ -104,6 +106,9 @@ $lang->repo->job = 'Job';
$lang->repo->fileServerUrl = 'File Server Url';
$lang->repo->fileServerAccount = 'File Server Account';
$lang->repo->fileServerPassword = 'File Server Password';
$lang->repo->linkStory = 'Link ' . $lang->SRCommon;
$lang->repo->linkBug = 'Link Bug';
$lang->repo->linkTask = 'Link Task';
$lang->repo->title = 'Tiêu đề';
$lang->repo->status = 'Tình trạng';
+5
View File
@@ -41,6 +41,8 @@ $lang->repo->downloadZip = '下载压缩包';
$lang->repo->sshClone = '使用SSH克隆';
$lang->repo->httpClone = '使用HTTP克隆';
$lang->repo->cloneUrl = '克隆地址';
$lang->repo->linkTask = '关联任务';
$lang->repo->unlinkedTasks = '未关联任务';
$lang->repo->submit = '提交';
$lang->repo->cancel = '取消';
@@ -104,6 +106,9 @@ $lang->repo->job = '构建任务';
$lang->repo->fileServerUrl = '预合并后上传服务器目录';
$lang->repo->fileServerAccount = '文件服务器登录用户名';
$lang->repo->fileServerPassword = '文件服务器登录密码';
$lang->repo->linkStory = '关联' . $lang->SRCommon;
$lang->repo->linkBug = '关联Bug';
$lang->repo->linkTask = '关联任务';
$lang->repo->title = '标题';
$lang->repo->status = '状态';
+124 -67
View File
@@ -313,6 +313,40 @@ class repoModel extends model
return true;
}
/**
* Create commit link.
*
* @param int $repoID
* @param string $revision
* @param string $type
* @access public
* @return void
*/
public function link($repoID, $revision, $type = 'story')
{
$this->loadModel('action');
if($type == 'story') $links = $this->post->stories;
if($type == 'bug') $links = $this->post->bugs;
if($type == 'task') $links = $this->post->tasks;
$revisionID = $this->dao->select('id')->from(TABLE_REPOHISTORY)->where('repo')->eq($repoID)->andWhere('revision')->eq($revision)->fetch('id');
foreach($links as $linkID)
{
$relation = new stdclass;
$relation->AType = 'revision';
$relation->AID = $revisionID;
$relation->relation = 'commit';
$relation->BType = $type;
$relation->BID = $linkID;
$this->dao->replace(TABLE_RELATION)->data($relation)->exec();
if($type == 'story') $this->action->create('story', $linkID, 'createmr');
if($type == 'bug') $this->action->create('bug', $linkID, 'createmr');
if($type == 'task') $this->action->create('task', $linkID, 'createmr');
}
}
/**
* Save repo state.
*
@@ -2505,6 +2539,96 @@ class repoModel extends model
return $output;
}
/**
* Get relation by commit.
*
* @param int $repoID
* @param string $commit
* @param string $type story|bug|task
* @access public
* @return array
*/
public function getRelationByCommit($repoID, $commit, $type = '')
{
$relationList = $this->dao->select('t1.BID as id, t1.BType as type')->from(TABLE_RELATION)->alias('t1')
->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.AID = t2.id')
->where('t2.revision')->eq($commit)
->andWhere('t2.repo')->eq($repoID)
->andWhere('t1.AType')->eq('revision')
->beginIF($type)->andWhere('t1.BType')->eq($type)->fi()
->fetchAll();
$storyIDs = array();
$bugIDs = array();
$taskIDs = array();
foreach($relationList as $relation)
{
if($relation->type == 'story')
{
$storyIDs[] = $relation->id;
}
elseif($relation->type == 'bug')
{
$bugIDs[] = $relation->id;
}
elseif($relation->type == 'task')
{
$taskIDs[] = $relation->id;
}
}
$stories = empty($storyIDs) ? array() : $this->loadModel('story')->getByList($storyIDs);
$bugs = empty($bugIDs) ? array() : $this->loadModel('bug')->getByList($bugIDs);
$tasks = empty($taskIDs) ? array() : $this->loadModel('task')->getByList($taskIDs);
$titleList = array();
foreach($relationList as $key => $relation)
{
if($type) $key = $relation->id;
$titleList[$key] = array(
'id' => $relation->id,
'type' => $relation->type,
'title' => "#$relation->id "
);
if($relation->type == 'story')
{
$story = zget($stories, $relation->id, array());
$titleList[$key]['title'] .= zget($story, 'title', '');
}
elseif($relation->type == 'bug')
{
$bug = zget($bugs, $relation->id, array());
$titleList[$key]['title'] .= zget($bug, 'title', '');
}
elseif($relation->type == 'task')
{
$task = zget($tasks, $relation->id, array());
$titleList[$key]['title'] .= zget($task, 'name', '');
}
}
return $titleList;
}
/**
* Get relation commit.
*
* @param int $objectID
* @param string $objectType story|bug|task
* @access public
* @return array
*/
public function getCommitsByObject($objectID, $objectType)
{
return $this->dao->select('t2.*')->from(TABLE_RELATION)->alias('t1')
->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.AID = t2.id')
->where('t1.BID')->eq($objectID)
->andWhere('t1.BType')->eq($objectType)
->andWhere('t1.AType')->eq('revision')
->andWhere('t1.relation')->eq('commit')
->fetchAll();
}
/**
* Insert delete record.
*
@@ -2587,71 +2711,4 @@ class repoModel extends model
$this->loadModel('setting')->setItem('system.repo.synced', $this->config->repo->synced . ',' . $repoID);
}
/**
* Get relation by commit.
*
* @param int $repoID
* @param string $commit
* @access public
* @return array
*/
public function getRelationByCommit($repoID, $commit)
{
$relationList = $this->dao->select('t1.BID as id, t1.BType as type')->from(TABLE_RELATION)->alias('t1')
->leftJoin(TABLE_REPOHISTORY)->alias('t2')
->on('t1.AID = t2.id')
->where('t2.revision')->eq($commit)
->andWhere('t2.repo')->eq($repoID)
->fetchAll();
$storyIDs = array();
$bugIDs = array();
$taskIDs = array();
foreach($relationList as $relation)
{
if($relation->type == 'story')
{
$storyIDs[] = $relation->id;
}
elseif($relation->type == 'bug')
{
$bugIDs[] = $relation->id;
}
elseif($relation->type == 'task')
{
$taskIDs[] = $relation->id;
}
}
$stories = empty($storyIDs) ? array() : $this->loadModel('story')->getByList($storyIDs);
$bugs = empty($bugIDs) ? array() : $this->loadModel('bug')->getByList($bugIDs);
$tasks = empty($taskIDs) ? array() : $this->loadModel('task')->getByList($taskIDs);
$titleList = array();
foreach($relationList as $key => $relation)
{
$titleList[$key] = array(
'id' => $relation->id,
'type' => $relation->type,
'title' => "#$relation->id "
);
if($relation->type == 'story')
{
$story = zget($stories, $relation->id, array());
$titleList[$key]['title'] .= zget($story, 'title', '');
}
elseif($relation->type == 'bug')
{
$bug = zget($bugs, $relation->id, array());
$titleList[$key]['title'] .= zget($bug, 'title', '');
}
elseif($relation->type == 'task')
{
$task = zget($tasks, $relation->id, array());
$titleList[$key]['title'] .= zget($task, 'name', '');
}
}
return $titleList;
}
}
+99 -79
View File
@@ -17,8 +17,13 @@ js::set('codeContent', trim($content));
js::set('file', $pathInfo);
js::set('blames', $blames);
js::set('blameTmpl', $lang->repo->blamTmpl);
js::set('repoID', $repoID);
js::import($jsRoot . '/zui/tabs/tabs.min.js');
js::import($jsRoot . 'monaco-editor/min/vs/loader.js');
$canLinkStory = common::hasPriv('repo', 'linkStory');
$canLinkBug = common::hasPriv('repo', 'linkBug');
$canLinkTask = common::hasPriv('repo', 'linkTask');
$canUnlinkObject = common::hasPriv('repo', 'unlinkObject');
?>
<div id="monacoEditor">
<div id="codeContainer"></div>
@@ -31,13 +36,14 @@ js::import($jsRoot . 'monaco-editor/min/vs/loader.js');
<div class="content panel">
<div class='btn-toolbar'>
<div class="btn btn-left pull-left"><i class="icon icon-chevron-left"></i></div>
<?php if(common::hasPriv('repo', 'blame') or common::hasPriv('repo', 'download')):?>
<?php if($canLinkStory or $canLinkBug or $canLinkTask or $canUnlinkObject):?>
<div class="dropdown pull-right">
<button class="btn" type="button" data-toggle="context-dropdown"><i class="icon icon-ellipsis-v icon-rotate-90"></i></button>
<ul class="dropdown-menu">
<?php
if(common::hasPriv('repo', 'blame')) echo '<li>' . html::a($this->repo->createLink('blame', ""), '<i class="icon icon-change"></i> ' . $lang->repo->blame, '', "data-app='{$app->tab}'") . '</li>';
if(common::hasPriv('repo', 'download')) echo '<li>' . html::a($this->repo->createLink('download', ""), '<i class="icon icon-download"></i> ' . $lang->repo->download, 'hiddenwin') . '</li>';
if($canLinkStory) echo '<li id="linkStory">' . html::a('javascript:;', '<i class="icon icon-lightbulb"></i> ' . $lang->repo->linkStory) . '</li>';
if($canLinkBug) echo '<li id="linkBug">' . html::a('javascript:;', '<i class="icon icon-bug"></i> ' . $lang->repo->linkBug) . '</li>';
if($canLinkTask) echo '<li id="linkTask">' . html::a('javascript:;', '<i class="icon icon-todo"></i> ' . $lang->repo->linkTask) . '</li>';
?>
</ul>
</div>
@@ -53,87 +59,90 @@ js::import($jsRoot . 'monaco-editor/min/vs/loader.js');
</div>
<?php include '../../common/view/footer.lite.html.php';?>
<script>
var codeHeight = $(window).innerHeight() - $('#mainHeader').height() - $('#appsBar').height() - $('#fileTabs .tabs-navbar').height();
if(codeHeight > 0) $.cookie('codeContainerHeight', codeHeight);
$('#codeContainer').css('height', $.cookie('codeContainerHeight'));
/**
* Get relation by commit.
*
* @param string $commit
* @access public
* @return void
*/
function getRelation(commit)
{
$('#codeContainer').css('height', codeHeight / 5 * 3);
var relatedHeight = codeHeight / 5 * 2 - $('#log').height() - 10;
$('#related').css('height', relatedHeight);
$tabs = $('#relationTabs').data('zui.tabs');
if($tabs) $tabs.closeAll();
$.post(createLink('repo', 'ajaxGetCommitRelation', 'commit=' + commit), function(data)
{
var titleList = JSON.parse(data).titleList;
var tabs = [];
$.each(titleList, function(i, titleObj)
{
var tab = setTab(titleObj);
if($tabs)
{
$tabs.open(tab);
}
else
{
tabs.push(tab);
}
});
if(titleList.length > 0)
{
if($tabs)
{
$tabs.open(setTab(titleList[0]));
}
else
{
$('#relationTabs').tabs({tabs: tabs});
}
}
arrowTabs('relationTabs', 1);
});
var linkStory = createLink('repo', 'linkStory', 'repoID=' + repoID + '&commit=' + commit, '', true);
var linkBug = createLink('repo', 'linkBug', 'repoID=' + repoID + '&commit=' + commit, '', true);
var linkTask = createLink('repo', 'linkTask', 'repoID=' + repoID + '&commit=' + commit, '', true);
$('#linkStory a').attr('data-link', linkStory);
$('#linkBug a').attr('data-link', linkBug);
$('#linkTask a').attr('data-link', linkTask);
$('#related').show();
}
/**
* Set tab data.
*
* @param object $titleObj
* @access public
* @return object
*/
function setTab(titleObj)
{
return {
id: titleObj.type + '-' + titleObj.id,
title: ' ' + titleObj.title,
icon: titleObj.type == 'story' ? 'icon-lightbulb' : (titleObj.type == 'task' ? 'icon-check-sign' : 'icon-bug'),
icon: titleObj.type == 'story' ? 'icon-lightbulb text-primary' : (titleObj.type == 'task' ? 'icon-check-sign text-info' : 'icon-bug text-red'),
type: 'iframe',
url: createLink('repo', 'ajaxGetRelationInfo', 'objectID=' + titleObj.id + '&objectType=' + titleObj.type)
};
}
$(function()
{
$('.btn-left').click(function() {arrowTabs('relationTabs', 1);});
$('.btn-right').click(function() {arrowTabs('relationTabs', -2);});
var codeHeight = $(window).innerHeight() - $('#mainHeader').height() - $('#appsBar').height() - $('#fileTabs .tabs-navbar').height();
if(codeHeight > 0) $.cookie('codeContainerHeight', codeHeight);
$('#codeContainer').css('height', $.cookie('codeContainerHeight'));
/**
* Get relation by commit.
*
* @param string $commit
* @access public
* @return void
*/
function getRelation(commit)
{
$('#codeContainer').css('height', codeHeight / 5 * 3);
var relatedHeight = codeHeight / 5 * 2 - $('#log').height() - 10;
$('#related').css('height', relatedHeight);
$tabs = $('#relationTabs').data('zui.tabs');
if($tabs) $tabs.closeAll();
$.post(createLink('repo', 'ajaxGetCommitRelation', 'commit=' + commit), function(data)
{
var titleList = JSON.parse(data).titleList;
var tabs = [];
$.each(titleList, function(i, titleObj)
{
var tab = setTab(titleObj);
if($tabs)
{
$tabs.open(tab);
}
else
{
tabs.push(tab);
}
});
if(titleList.length > 0)
{
if($tabs)
{
$tabs.open(setTab(titleList[0]));
}
else
{
$('#relationTabs').tabs({tabs: tabs});
}
}
arrowTabs('relationTabs', 1);
});
$('#related').show();
}
$('#relationTabs').on('onOpen', function(event, tab) {
var relatedHeight = codeHeight / 5 * 2 - $('#log').height() - 45;
$('#relationTabs iframe').css('height', relatedHeight);
});
/**
* Set tab data.
*
* @param object $titleObj
* @access public
* @return object
*/
function setTab(titleObj)
{
return {
id: titleObj.type + '-' + titleObj.id,
title: ' ' + titleObj.title,
icon: titleObj.type == 'story' ? 'icon-lightbulb text-primary' : (titleObj.type == 'task' ? 'icon-check-sign text-info' : 'icon-bug text-red'),
type: 'iframe',
url: createLink('repo', 'ajaxGetRelationInfo', 'objectID=' + titleObj.id + '&objectType=' + titleObj.type)
};
}
require.config({
paths: {vs: jsRoot + 'monaco-editor/min/vs'},
'vs/nls': {
@@ -187,5 +196,16 @@ $(function()
getRelation(blame.revision);
})
});
$('#linkStory a, #linkBug a, #linkTask a').on('click', function()
{
var link = $(this).data('link');
parent.loadLinkPage(link);
});
$('#relationTabs').on('onOpen', function(event, tab) {
var relatedHeight = codeHeight / 5 * 2 - $('#log').height() - 45;
$('#relationTabs iframe').css('height', relatedHeight);
});
});
</script>
+82
View File
@@ -0,0 +1,82 @@
<?php
/**
* The link bug view of productplan module of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package mr
* @version $Id: linkbug.html.php$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/sortable.html.php';?>
<?php include '../../common/view/tablesorter.html.php';?>
<style>
#queryBox {padding-top: 25px;}
</style>
<div id='queryBox' data-module='bug' class='show no-margin'></div>
<div id='unlinkBugList'>
<form class='main-table table-bug' data-ride='table' method='post' id='unlinkedBugsForm' target='hiddenwin' action='<?php echo $this->createLink('repo', 'linkBug', "repoID=$repoID&revision=$revision&browseType=$browseType&param=$param&orderBy=$orderBy")?>'>
<div class='table-header hl-primary text-primary strong'>
<?php echo html::icon('unlink');?> <?php echo $lang->productplan->unlinkedBugs;?>
</div>
<table class='table tablesorter'>
<thead>
<tr class='text-center'>
<th class='c-id text-left'>
<?php if($allBugs):?>
<div class="checkbox-primary check-all tablesorter-noSort" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php endif;?>
<?php echo $lang->idAB;?>
</th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php echo $lang->priAB;?></th>
<th class='text-left'><?php echo $lang->bug->title;?></th>
<th class='c-user'><?php echo $lang->openedByAB;?></th>
<th class='c-user'><?php echo $lang->bug->assignedToAB;?></th>
<th class='c-status'><?php echo $lang->bug->status;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allBugs as $bug):?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('bugs', array($bug->id => sprintf('%03d', $bug->id)));?>
</td>
<td><span class='label-pri label-pri-<?php echo $bug->pri;?>' title='<?php echo zget($lang->bug->priList, $bug->pri, $bug->pri)?>'><?php echo zget($lang->bug->priList, $bug->pri, $bug->pri)?></span></td>
<td class='text-left nobr' title='<?php echo $bug->title?>'><?php echo html::a($this->createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?></td>
<td><?php echo zget($users, $bug->openedBy);?></td>
<td><?php echo zget($users, $bug->assignedTo);?></td>
<td>
<span class='status-bug status-<?php echo $bug->status?>'>
<?php echo $this->processStatus('bug', $bug);?>
</span>
</td>
</tr>
<?php $unlinkedCount++;?>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'>
<?php if($unlinkedCount):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php echo html::submitButton($lang->productplan->linkBug, '', 'btn');?>
</div>
<?php endif;?>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
</div>
<script>
$(function()
{
$('#unlinkBugList .tablesorter').sortTable();
setForm();
});
</script>
+93
View File
@@ -0,0 +1,93 @@
<?php
/**
* The link story view of repo module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author yuchun li
* @package repo
* @version $Id: linkstory.html.php 5096 2022-07-25 07:02:43Z liycuhun@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/sortable.html.php';?>
<?php include '../../common/view/tablesorter.html.php';?>
<div class='main-content' id='mainContent'>
<div class='main-header'> </div>
<div id='queryBox' data-module='story' class='show no-margin'></div>
<form class="main-table table-story" data-ride="table" method="post" target='hiddenwin' id='linkStoryForm' action="<?php echo $this->createLink('repo', 'linkStory', "repoID=$repoID&revision=$revision&browseType=$browseType&param=$param&orderBy=$orderBy")?>">
<div class='table-header hl-primary text-primary strong'>
<?php echo html::icon('unlink');?> <?php echo $lang->productplan->unlinkedStories;?>
</div>
<table class='table tablesorter'>
<thead>
<tr>
<th class='c-id text-left'>
<?php if($allStories):?>
<div class="checkbox-primary check-all tablesorter-noSort" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php endif;?>
<?php echo $lang->idAB;?>
</th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php echo $lang->priAB;?></th>
<th class='c-plan'><?php echo $lang->story->plan;?></th>
<th class='c-module'><?php echo $lang->story->module;?></th>
<th class='text-left'><?php echo $lang->story->title;?></th>
<th class='c-user'><?php echo $lang->openedByAB;?></th>
<th class='c-user'><?php echo $lang->assignedToAB;?></th>
<th class='c-number text-right'><?php echo $lang->story->estimateAB;?></th>
<th class='c-status'><?php echo $lang->statusAB;?></th>
<th class='c-stage'><?php echo $lang->story->stageAB;?></th>
</tr>
</thead>
<tbody>
<?php $unlinkedCount = 0;?>
<?php foreach($allStories as $story):?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('stories', array($story->id => sprintf('%03d', $story->id)));?>
</td>
<td><span class='label-pri <?php echo 'label-pri-' . $story->pri;?>' title='<?php echo zget($lang->story->priList, $story->pri, $story->pri)?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
<td><?php echo $story->planTitle;?></td>
<td title='<?php echo zget($modules, $story->module, '/')?>' class='text-left'><?php echo zget($modules, $story->module, '/');?></td>
<td class='text-left nobr' title='<?php echo $story->title?>'>
<?php
if($story->parent > 0) echo "<span class='label label-badge label-light' title={$lang->story->children}>{$lang->story->childrenAB}</span>";
echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");
?>
</td>
<td><?php echo zget($users, $story->openedBy);?></td>
<td><?php echo zget($users, $story->assignedTo);?></td>
<td class='text-right'title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
<td>
<span class='status-story status-<?php echo $story->status?>'>
<?php echo $this->processStatus('story', $story);?>
</span>
</td>
<td class='text-center'><?php echo $lang->story->stageList[$story->stage];?></td>
</tr>
<?php $unlinkedCount++;?>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'>
<?php if($unlinkedCount):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php echo html::submitButton($lang->productplan->linkStory, '', 'btn');?>
</div>
<?php endif;?>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
</div>
<script>
$(function()
{
$('#unlinkStoryList .tablesorter').sortTable();
setForm();
});
</script>
+82
View File
@@ -0,0 +1,82 @@
<?php
/**
* The link task view of repo module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yuchun Li <liyuchun@easycorp.ltd>
* @package repo
* @version $Id: linktask.html.php$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/sortable.html.php';?>
<?php include '../../common/view/tablesorter.html.php';?>
<style>
#queryBox {padding-top: 25px;}
</style>
<div id='queryBox' data-module='task' class='show no-margin'></div>
<div id='unlinkTaskList'>
<form class='main-table table-task' data-ride='table' method='post' id='unlinkedTasksForm' target='hiddenwin' action='<?php echo $this->createLink('repo', 'linkTask', "repoID=$repoID&revision=$revision&browseType=$browseType&param=$param&orderBy=$orderBy")?>'>
<div class='table-header hl-primary text-primary strong'>
<?php echo html::icon('unlink');?> <?php echo $lang->repo->unlinkedTasks;?>
</div>
<table class='table tablesorter'>
<thead>
<tr class='text-center'>
<th class='c-id text-left'>
<?php if($allTasks):?>
<div class="checkbox-primary check-all tablesorter-noSort" title="<?php echo $lang->selectAll?>">
<label></label>
</div>
<?php endif;?>
<?php echo $lang->idAB;?>
</th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php echo $lang->priAB;?></th>
<th class='text-left'><?php echo $lang->task->name;?></th>
<th class='c-user'><?php echo $lang->task->finishedByAB;?></th>
<th class='c-user'><?php echo $lang->task->assignedToAB;?></th>
<th class='c-status'><?php echo $lang->task->status;?></th>
</tr>
</thead>
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allTasks as $task):?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('tasks', array($task->id => sprintf('%03d', $task->id)));?>
</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 zget($lang->task->priList, $task->pri, $task->pri)?></span></td>
<td class='text-left nobr' title='<?php echo $task->name?>'><?php echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), $task->name, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?></td>
<td><?php echo zget($users, $task->finishedBy);?></td>
<td><?php echo zget($users, $task->assignedTo);?></td>
<td>
<span class='status-task status-<?php echo $task->status?>'>
<?php echo $this->processStatus('task', $task);?>
</span>
</td>
</tr>
<?php $unlinkedCount++;?>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'>
<?php if($unlinkedCount):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php echo html::submitButton($lang->repo->linkTask, '', 'btn');?>
</div>
<?php endif;?>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
</div>
<script>
$(function()
{
$('#unlinkTaskList .tablesorter').sortTable();
setForm();
});
</script>
+1
View File
@@ -77,4 +77,5 @@ $encodePath = $this->repo->encodePath($entry);
<?php if(!isonlybody()):?>
</div>
<?php endif;?>
<a href='' class='iframe' data-width='90%' id='linkObject'></a>
<?php include '../../common/view/footer.html.php';?>
+2
View File
@@ -1261,6 +1261,7 @@ class story extends control
$fromBug = $this->dao->select('id,title')->from(TABLE_BUG)->where('toStory')->eq($storyID)->fetch();
$cases = $this->dao->select('id,title,status,pri')->from(TABLE_CASE)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->fetchAll();
$linkedMRs = $this->loadModel('mr')->getLinkedMRPairs($storyID, 'story');
$linkedCommits = $this->loadModel('repo')->getCommitsByObject($storyID, 'story');
$modulePath = $this->tree->getParents($story->module);
$storyModule = empty($story->module) ? '' : $this->tree->getById($story->module);
$linkedStories = isset($story->linkStoryTitles) ? array_keys($story->linkStoryTitles) : array();
@@ -1308,6 +1309,7 @@ class story extends control
$this->view->cases = $cases;
$this->view->story = $story;
$this->view->linkedMRs = $linkedMRs;
$this->view->linkedCommits = $linkedCommits;
$this->view->track = $this->story->getTrackByID($story->id);
$this->view->users = $this->user->getPairs('noletter');
$this->view->reviewers = $reviewers;
+1
View File
@@ -181,6 +181,7 @@ $lang->story->completeRate = 'Completion Rate';
$lang->story->reviewed = 'Reviewed';
$lang->story->toBeReviewed = 'To Be Reviewed';
$lang->story->linkMR = 'Related MRs';
$lang->story->linkCommit = 'Related Commits';
$lang->story->ditto = 'Dito';
$lang->story->dittoNotice = 'Die Story gehört nicht zum Projekt wie die vorherige!';
+1
View File
@@ -181,6 +181,7 @@ $lang->story->completeRate = 'Completion Rate';
$lang->story->reviewed = 'Reviewed';
$lang->story->toBeReviewed = 'To Be Reviewed';
$lang->story->linkMR = 'Related MRs';
$lang->story->linkCommit = 'Related Commits';
$lang->story->ditto = 'Ditto';
$lang->story->dittoNotice = 'This story is not linked to the same product as the last one is!';
+1
View File
@@ -181,6 +181,7 @@ $lang->story->completeRate = 'Completion Rate';
$lang->story->reviewed = 'Reviewed';
$lang->story->toBeReviewed = 'To Be Reviewed';
$lang->story->linkMR = 'Related MRs';
$lang->story->linkCommit = 'Related Commits';
$lang->story->ditto = 'Idem';
$lang->story->dittoNotice = "La story n'est pas associée au même product que la précédente !";
+1
View File
@@ -175,6 +175,7 @@ $lang->story->completeRate = 'Completion Rate';
$lang->story->reviewed = 'Reviewed';
$lang->story->toBeReviewed = 'To Be Reviewed';
$lang->story->linkMR = 'Related MRs';
$lang->story->linkCommit = 'Related Commits';
$lang->story->ditto = 'Như trên';
$lang->story->dittoNotice = 'Câu chuyện này chưa liên kết tới cùng sản phẩm bởi bởi vì nó là cuối cùng!';
+1
View File
@@ -181,6 +181,7 @@ $lang->story->completeRate = '完成率';
$lang->story->reviewed = '已评审';
$lang->story->toBeReviewed = '待评审';
$lang->story->linkMR = '相关合并请求';
$lang->story->linkCommit = '相关代码版本';
$lang->story->ditto = '同上';
$lang->story->dittoNotice = "该{$lang->SRCommon}与上一{$lang->SRCommon}不属于同一产品!";
+23
View File
@@ -574,6 +574,29 @@
</ul>
</td>
</tr>
<tr>
<th><?php echo $lang->story->linkCommit;?></th>
<td class='pd-0'>
<ul class='list-unstyled'>
<?php
$canViewRevision = common::hasPriv('repo', 'revision');
foreach($linkedCommits as $commit)
{
$revision = substr($commit->revision, 0, 10);
$commitTitle = $revision . ' ' . $commit->comment;
if($canViewRevision)
{
echo "<li title='$commitTitle'>" . html::a($this->createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}"), "$commitTitle") . '</li>';
}
else
{
echo "<li title='$commitTitle'>" . "$commitTitle" . '</li>';
}
}
?>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
+1
View File
@@ -993,6 +993,7 @@ class task extends control
$this->view->product = $this->tree->getProduct($task->module);
$this->view->modulePath = $this->tree->getParents($task->module);
$this->view->linkMRTitles = $this->loadModel('mr')->getLinkedMRPairs($taskID, 'task');
$this->view->linkCommits = $this->loadModel('repo')->getCommitsByObject($taskID, 'task');
$this->display();
}
+1
View File
@@ -170,6 +170,7 @@ $lang->task->noClosed = 'Niht geschlossen';
$lang->task->yesterdayFinished = 'Gestern abgeschlossen';
$lang->task->allTasks = 'Alle Aufgaben';
$lang->task->linkMR = 'Related MRs';
$lang->task->linkCommit = 'Related Commits';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = 'Wartend';
+1
View File
@@ -170,6 +170,7 @@ $lang->task->noClosed = 'Unclosed';
$lang->task->yesterdayFinished = 'Task Finished Yesterday';
$lang->task->allTasks = 'Task';
$lang->task->linkMR = 'Related MRs';
$lang->task->linkCommit = 'Related Commits';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = 'Waiting';
+1
View File
@@ -170,6 +170,7 @@ $lang->task->noClosed = 'Non Fermées';
$lang->task->yesterdayFinished = 'Tâche Terminée Hier';
$lang->task->allTasks = 'Tâche';
$lang->task->linkMR = 'Related MRs';
$lang->task->linkCommit = 'Related Commits';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = 'A Faire';
+2
View File
@@ -142,6 +142,8 @@ $lang->task->noFinished = 'Chưa kết thúc';
$lang->task->noClosed = 'Chưa đóng';
$lang->task->yesterdayFinished = 'Kết thúc hôm qua';
$lang->task->allTasks = 'Nhiệm vụ';
$lang->task->linkMR = 'Related MRs';
$lang->task->linkCommit = 'Related Commits';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = 'Đang đợi';
+2 -1
View File
@@ -170,6 +170,7 @@ $lang->task->noClosed = '未关闭';
$lang->task->yesterdayFinished = '昨日完成任务数';
$lang->task->allTasks = '总任务';
$lang->task->linkMR = '相关合并请求';
$lang->task->linkCommit = '相关代码版本';
$lang->task->statusList[''] = '';
$lang->task->statusList['wait'] = '未开始';
@@ -354,4 +355,4 @@ $lang->taskestimate = new stdclass();
$lang->taskestimate->consumed = '工时';
$lang->task->overEsStartDate = '已超出%s计划开始时间,请先修改%s计划开始时间';
$lang->task->overEsEndDate = '已超出%s计划结束时间,请先修改%s计划结束时间';
$lang->task->overEsEndDate = '已超出%s计划结束时间,请先修改%s计划结束时间';
+13
View File
@@ -419,6 +419,19 @@
?>
</td>
</tr>
<tr>
<th class='MRThWidth'><?php echo $lang->task->linkCommit;?></th>
<td>
<?php
$canViewRevision = common::hasPriv('repo', 'revision');
foreach($linkCommits as $commit)
{
$revision = substr($commit->revision, 0, 10);
echo ($canViewRevision ? html::a($this->createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}"), "$revision {$commit->comment}") : "$revisioin {$commit->comment}") . '<br />';
}
?>
</td>
</tr>
</table>
</div>
</div>