* Finish task #70792: link project without product to code repository.

This commit is contained in:
wangjianhua
2022-09-30 14:20:19 +08:00
parent 0c11f5b232
commit 04702a6139
13 changed files with 192 additions and 1 deletions
+2 -1
View File
@@ -212,7 +212,7 @@ $lang->scrum->menu->devops = array('link' => "{$lang->repo->common}|repo|br
$lang->scrum->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s");
$lang->scrum->menu->release = array('link' => "{$lang->release->common}|projectrelease|browse|project=%s", 'subModule' => 'projectrelease');
$lang->scrum->menu->dynamic = array('link' => "$lang->dynamic|project|dynamic|project=%s");
$lang->scrum->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team');
$lang->scrum->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team,managerepo');
$lang->scrum->menu->storyGroup['dropMenu'] = new stdclass();
$lang->scrum->menu->storyGroup['dropMenu']->story = array('link' => "{$lang->SRCommon}|projectstory|story|projectID=%s&productID=%s", 'subModule' => 'projectstory,tree');
@@ -251,6 +251,7 @@ $lang->scrum->menu->settings['subMenu']->whitelist = array('link' => "{$lang->
$lang->scrum->menu->settings['subMenu']->stakeholder = array('link' => "{$lang->stakeholder->common}|stakeholder|browse|project=%s", 'subModule' => 'stakeholder');
$lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang->priv}|project|group|project=%s", 'alias' => 'group,manageview,managepriv');
$lang->scrum->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story");
$lang->scrum->menu->settings['subMenu']->managerepo = array('link' => "{$lang->repo->common}|project|managerepo|project=%s");
/* Waterfall menu. */
$lang->waterfall->menu = new stdclass();
+2
View File
@@ -191,6 +191,7 @@ $lang->resource->project->updateOrder = 'updateOrder';
$lang->resource->project->team = 'teamAction';
$lang->resource->project->unlinkMember = 'unlinkMember';
$lang->resource->project->programTitle = 'moduleOpen';
$lang->resource->project->manageRepo = 'manageRepo';
$lang->project->methodOrder[0] = 'index';
$lang->project->methodOrder[5] = 'browse';
@@ -230,6 +231,7 @@ $lang->project->methodOrder[170] = 'export';
$lang->project->methodOrder[175] = 'updateOrder';
$lang->project->methodOrder[180] = 'team';
$lang->project->methodOrder[185] = 'unlinkMember';
$lang->project->methodOrder[190] = 'manageRepo';
$lang->resource->projectbuild = new stdclass();
$lang->resource->projectbuild->browse = 'browse';
+32
View File
@@ -2244,4 +2244,36 @@ class project extends control
if($this->app->getViewType() == 'json') return print(json_encode($executionList));
return print(html::select('execution', $executions, $executionID, "class='form-control'"));
}
/**
* Link project and repo.
*
* @param int $projectID
* @access public
* @return void
*/
public function manageRepo($projectID)
{
$this->project->setMenu($projectID);
if($_POST)
{
$postData = fixer::input('post')->setDefault('repos', array())->get();
$this->project->updateRepoRelations($projectID, $postData->repos);
$locateLink = inLink('manageRepo', "projectID=$projectID");
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink));
}
$this->view->title = $this->lang->project->manageRepo;
$this->view->allRepos = $this->dao->select('*')->from(TABLE_REPO)->where('deleted')->eq(0)->fetchPairs('id', 'name');
$this->view->linkedRepos = $this->project->linkedRepoPairs($projectID);
$this->view->unlinkedRepos = array();
foreach($this->view->allRepos as $repoID => $repoName) if(!isset($this->view->linkedRepos[$repoID])) $this->view->unlinkedRepos[$repoID] = $repoName;
$this->display();
}
}
+10
View File
@@ -0,0 +1,10 @@
#reposBox .repo {border: 1px solid #ddd; margin-bottom: 5px; position: relative; height: 40px; border-radius: 4px;}
#reposBox .repo:hover {background: #f1f1f1;}
#reposBox .repo.checked,
#reposBox .repo.checked:hover {background: #E5FFE6; border: 1px solid #229F24;}
#reposBox .repo .checkbox-primary {padding: 9px; cursor: pointer;}
#reposBox .repo.has-branch {padding-right: 40%;}
#reposBox .repo.has-branch > .chosen-container {position: absolute; width: 40% !important; right: 3px; top: 3px;}
#reposBox .repo.has-branch > .chosen-container > .chosen-single {background: rgba(0,0,0,.05);}
#reposBox .repo.has-branch > .chosen-container > .chosen-single:hover {background: #fff;}
#reposBox .chosen-container .chosen-results{max-height: 180px;}
+14
View File
@@ -0,0 +1,14 @@
$(function()
{
$('#reposBox input:checkbox').each(function()
{
var $cb = $(this);
if($cb.prop('checked')) $cb.closest('.repo').addClass('checked');
});
$('#reposBox input:checkbox').change(function()
{
var $cb = $(this);
$cb.closest('.repo').toggleClass('checked', $cb.prop('checked'));
});
});
+3
View File
@@ -64,6 +64,9 @@ $lang->project->budgetNumber = '『Budget』must be numbers.';
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
$lang->project->allProjects = 'All Projects';
$lang->project->ignore = 'Ignore';
$lang->project->manageRepo = 'Manage Repo';
$lang->project->linkedRepo = 'Link Repo';
$lang->project->unlinkedRepo = 'Unlink Repo';
/* Fields. */
$lang->project->common = 'Project';
+3
View File
@@ -64,6 +64,9 @@ $lang->project->budgetNumber = '『Budget』must be numbers.';
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
$lang->project->allProjects = 'All Projects';
$lang->project->ignore = 'Ignore';
$lang->project->manageRepo = 'Manage Repo';
$lang->project->linkedRepo = 'Link Repo';
$lang->project->unlinkedRepo = 'Unlink Repo';
/* Fields. */
$lang->project->common = 'Project';
+3
View File
@@ -64,6 +64,9 @@ $lang->project->budgetNumber = '『Budget』must be numbers.';
$lang->project->budgetGe0 = '『Budget』must be greater than or equal to 0.';
$lang->project->allProjects = 'All Projects';
$lang->project->ignore = 'Ignorer';
$lang->project->manageRepo = 'Manage Repo';
$lang->project->linkedRepo = 'Link Repo';
$lang->project->unlinkedRepo = 'Unlink Repo';
/* Fields. */
$lang->project->common = 'Projets';
+3
View File
@@ -51,6 +51,9 @@ $lang->project->unlinkedProducts = "Unlinked {$lang->productCommon}s";
$lang->project->testreport = 'Testreport';
$lang->project->selectProgram = 'Program filtering';
$lang->project->teamMember = 'Team Member';
$lang->project->manageRepo = 'Manage Repo';
$lang->project->linkedRepo = 'Link Repo';
$lang->project->unlinkedRepo = 'Unlink Repo';
/* Fields. */
$lang->project->common = 'Project';
+3
View File
@@ -64,6 +64,9 @@ $lang->project->budgetNumber = '『预算』金额必须为数字。';
$lang->project->budgetGe0 = '『预算』金额必须大于等于0。';
$lang->project->allProjects = '所有项目';
$lang->project->ignore = '忽略';
$lang->project->manageRepo = '关联代码库';
$lang->project->linkedRepo = '已关联代码库';
$lang->project->unlinkedRepo = '未关联代码库';
/* Fields. */
$lang->project->common = '项目';
+3
View File
@@ -55,6 +55,9 @@ $lang->project->selectProgram = '項目集篩選';
$lang->project->teamMember = '團隊成員';
$lang->project->unlinkMember = '移除成員';
$lang->project->copyTeamTitle = '選擇一個項目團隊來複制';
$lang->project->manageRepo = '關聯代碼庫';
$lang->project->linkedRepo = '已關聯代碼庫';
$lang->project->unlinkedRepo = '未關聯代碼庫';
/* Fields. */
$lang->project->common = '項目';
+55
View File
@@ -2576,6 +2576,7 @@ class projectModel extends model
else
{
unset($lang->project->menu->settings['subMenu']->module);
unset($lang->project->menu->settings['subMenu']->managerepo);
unset($lang->project->menu->projectplan);
}
@@ -2842,4 +2843,58 @@ class projectModel extends model
return $menu;
}
/**
* Update linked repos.
*
* @param int $projectID
* @param array $repos
* @access public
* @return void
*/
public function updateRepoRelations($projectID, $repos)
{
/* Delete old relations. */
$this->dao->delete()->from(TABLE_RELATION)
->where('AType')->eq('project')
->andWhere('AID')->eq($projectID)
->andWhere('BType')->eq('repo')
->exec();
/* Insert new relations. */
foreach($repos as $repoID)
{
$newRelation = new stdclass;
$newRelation->AType = 'project';
$newRelation->AID = $projectID;
$newRelation->BType = 'repo';
$newRelation->BID = $repoID;
$this->dao->insert(TABLE_RELATION)->data($newRelation)->exec();
}
}
/**
* Get linked repo pairs by project id.
*
* @param int $projectID
* @access public
* @return array
*/
public function linkedRepoPairs($projectID)
{
$repoIDList = $this->dao->select('BID')->from(TABLE_RELATION)
->where('AType')->eq('project')
->andWhere('AID')->eq($projectID)
->andWhere('BType')->eq('repo')
->fetchPairs('BID', 'BID');
$repos = $this->dao->select('*')->from(TABLE_REPO)
->where('deleted')->eq(0)
->andWhere('id')->in($repoIDList)
->fetchPairs('id', 'name');
return $repos;
}
}
+59
View File
@@ -0,0 +1,59 @@
<?php
/**
* The manage repo view of project module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(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 project
* @version $Id
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<span class='btn btn-link btn-active-text'><span class='text'><?php echo $lang->project->manageRepo;?></span></span>
</div>
</div>
<div id='mainContent'>
<div class='cell'>
<form class='main-form form-ajax' method='post' id='reposBox' enctype='multipart/form-data'>
<div class='detail'>
<div class='detail-title'><?php echo $lang->project->linkedRepo;?></div>
<div class='detail-content row'>
<?php foreach($linkedRepos as $repoID => $repoName):?>
<div class='col-sm-4'>
<div class='repo checked'>
<div class="checkbox-primary" title='<?php echo $repoName;?>'>
<?php echo "<input type='checkbox' name='repos[$repoID]' value='$repoID' checked id='repos{$repoID}'>";?>
<label class='text-ellipsis checkbox-inline' for='<?php echo 'repos' . $repoID;?>' title='<?php echo $repoName;?>'><?php echo $repoName;?></label>
</div>
</div>
</div>
<?php endforeach;?>
</div>
</div>
<div class='detail'>
<div class='detail-title'><?php echo $lang->project->unlinkedRepo;?></div>
<div class='detail-content row'>
<?php foreach($unlinkedRepos as $repoID => $repoName):?>
<div class='col-sm-4'>
<div class='repo'>
<div class="checkbox-primary" title='<?php echo $repoName;?>'>
<?php echo "<input type='checkbox' name='repos[$repoID]' value='$repoID' id='repos{$repoID}'>";?>
<label class='text-ellipsis checkbox-inline' for='<?php echo 'repos' . $repoID;?>'><?php echo $repoName;?></label>
</div>
</div>
</div>
<?php endforeach;?>
</div>
</div>
<div class="detail text-center form-actions">
<?php echo html::hidden("post", 'post');?>
<?php echo html::submitButton();?>
</div>
</form>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>