Merge branch 'sprint/170' into 'sprint/170_xieqiyu_43919'

# Conflicts:
#   db/zentao.sql
This commit is contained in:
胡方舟
2021-11-05 06:56:47 +00:00
45 changed files with 246 additions and 66 deletions
+6
View File
@@ -0,0 +1,6 @@
ALTER TABLE `zt_branch` ADD `default` enum ('0', '1') NOT NULL DEFAULT '0' AFTER `name`;
ALTER TABLE `zt_branch` ADD `status` enum ('active', 'closed') NOT NULL DEFAULT 'active' AFTER `default`;
ALTER TABLE `zt_branch` ADD `desc` varchar(255) NOT NULL AFTER `status`;
ALTER TABLE `zt_branch` ADD `createdDate` date NOT NULL AFTER `desc`;
ALTER TABLE `zt_branch` ADD `closedDate` date NOT NULL AFTER `createdDate`;
ALTER TABLE `zt_projectproduct` ADD PRIMARY KEY `project_product_branch` (`project`, `product`, `branch`), DROP INDEX `PRIMARY`;
+3 -3
View File
@@ -147,8 +147,8 @@ CREATE TABLE IF NOT EXISTS `zt_branch` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`status` enum('active','closed') NOT NULL default 'active',
`default` enum('0','1') NOT NULL default '0',
`default` enum ('0', '1') NOT NULL DEFAULT '0'
`status` enum ('active', 'closed') NOT NULL DEFAULT 'active'
`desc` varchar(255) NOT NULL,
`createdDate` date NOT NULL,
`closedDate` date NOT NULL,
@@ -837,7 +837,7 @@ CREATE TABLE IF NOT EXISTS `zt_projectproduct` (
`product` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`plan` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`project`,`product`)
PRIMARY KEY (`project`,`product`, `branch`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_projectspec`;
CREATE TABLE IF NOT EXISTS `zt_projectspec` (
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Hinzufügen';
$lang->branch->manageTitle = '%s Management';
$lang->branch->all = 'Alle ';
$lang->branch->main = 'Main';
$lang->branch->create = 'Create Branch';
$lang->branch->merge = 'Merge';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Add';
$lang->branch->manageTitle = '%s Management';
$lang->branch->all = 'All ';
$lang->branch->main = 'Main';
$lang->branch->create = 'Create Branch';
$lang->branch->merge = 'Merge';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Ajout';
$lang->branch->manageTitle = 'Gestion %s';
$lang->branch->all = 'Tous';
$lang->branch->main = 'Main';
$lang->branch->create = 'Create Branch';
$lang->branch->merge = 'Merge';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = 'Thêm';
$lang->branch->manageTitle = 'Quản lý %s';
$lang->branch->all = 'Tất cả ';
$lang->branch->main = 'Main';
$lang->branch->create = 'Create Branch';
$lang->branch->merge = 'Merge';
+1
View File
@@ -7,6 +7,7 @@ $lang->branch->add = '添加';
$lang->branch->manageTitle = '%s管理';
$lang->branch->all = '所有';
$lang->branch->main = '主干';
$lang->branch->create = '新增分支';
$lang->branch->merge = '合并';
+4 -7
View File
@@ -25,7 +25,7 @@ class branchModel extends model
if(empty($productID)) $productID = $this->session->product;
$product = $this->loadModel('product')->getById($productID);
if(empty($product) or !isset($this->lang->product->branchName[$product->type])) return false;
return $this->lang->branch->all . $this->lang->product->branchName[$product->type];
return $this->lang->branch->main;
}
return htmlspecialchars_decode($this->dao->select('*')->from(TABLE_BRANCH)->where('id')->eq($branchID)->fetch('name'));
}
@@ -90,7 +90,7 @@ class branchModel extends model
$product = $this->loadModel('product')->getById($productID);
if(!$product or $product->type == 'normal') return array();
$branches = array('0' => $this->lang->branch->all . $this->lang->product->branchName[$product->type]) + $branches;
$branches = array('all' => $this->lang->branch->all, '0' => $this->lang->branch->main) + $branches;
}
return $branches;
}
@@ -119,10 +119,7 @@ class branchModel extends model
}
}
if(strpos($params, 'noempty') === false)
{
$branchPairs = array('0' => $this->lang->branch->all . $this->lang->product->branchName['branch']) + $branchPairs;
}
if(strpos($params, 'noempty') === false) $branchPairs = array('0' => $this->lang->branch->main) + $branchPairs;
return $branchPairs;
}
@@ -192,7 +189,7 @@ class branchModel extends model
if($product->type == 'normal') continue;
if(!isset($branchGroups[$product->id])) $branchGroups[$product->id] = array();
if(strpos($params, 'noempty') === false) $branchGroups[$product->id] = array('0' => $this->lang->branch->all . $this->lang->product->branchName[$product->type]) + $branchGroups[$product->id];
if(strpos($params, 'noempty') === false) $branchGroups[$product->id] = array('0' => $this->lang->branch->main) + $branchGroups[$product->id];
}
return $branchGroups;
+2
View File
@@ -71,6 +71,7 @@ $config->bug->search['fields']['resolvedBy'] = $lang->bug->resolvedBy;
$config->bug->search['fields']['status'] = $lang->bug->status;
$config->bug->search['fields']['confirmed'] = $lang->bug->confirmed;
if($config->systemMode == 'new') $config->bug->search['fields']['project'] = $lang->bug->project;
$config->bug->search['fields']['product'] = $lang->bug->product;
$config->bug->search['fields']['branch'] = '';
$config->bug->search['fields']['plan'] = $lang->bug->productplan;
@@ -114,6 +115,7 @@ $config->bug->search['params']['resolvedBy'] = array('operator' => '=',
$config->bug->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->statusList);
$config->bug->search['params']['confirmed'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->confirmedList);
if($config->systemMode == 'new') $config->bug->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->bug->search['params']['product'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->bug->search['params']['branch'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->bug->search['params']['plan'] = array('operator' => '=', 'control' => 'select', 'values' => '');
+1 -1
View File
@@ -1776,7 +1776,7 @@ class bug extends control
$relatedTasks = $this->dao->select('id, name')->from(TABLE_TASK)->where('id')->in($relatedTaskIdList)->fetchPairs();
$relatedBugs = $this->dao->select('id, title')->from(TABLE_BUG)->where('id')->in($relatedBugIdList)->fetchPairs();
$relatedCases = $this->dao->select('id, title')->from(TABLE_CASE)->where('id')->in($relatedCaseIdList)->fetchPairs();
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBuilds = array('trunk' => $this->lang->trunk) + $this->dao->select('id, name')->from(TABLE_BUILD)->where('id')->in($relatedBuildIdList)->fetchPairs();
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('bug')->andWhere('objectID')->in(@array_keys($bugs))->andWhere('extra')->ne('editor')->fetchGroup('objectID');
$relatedModules = $this->loadModel('tree')->getAllModulePairs('bug');
+1
View File
@@ -133,6 +133,7 @@ $lang->bug->overdueBugs = 'Überfällig';
$lang->bug->allBugs = 'Alle';
$lang->bug->byQuery = 'Suche';
$lang->bug->needConfirm = 'Story geändert';
$lang->bug->allProject = 'All Projects';
$lang->bug->allProduct = 'Alle' . $lang->productCommon;
$lang->bug->my = 'Meine';
$lang->bug->yesterdayResolved = 'Gestern gelöst ';
+2 -1
View File
@@ -140,7 +140,8 @@ $lang->bug->overdueBugs = 'Overdue';
$lang->bug->allBugs = 'All Bugs';
$lang->bug->byQuery = 'Search';
$lang->bug->needConfirm = 'Story Changed';
$lang->bug->allProduct = 'All' . $lang->productCommon . 's';
$lang->bug->allProject = 'All Projects';
$lang->bug->allProduct = 'All ' . $lang->productCommon . 's';
$lang->bug->my = 'My';
$lang->bug->yesterdayResolved = 'Bug Resolved Yesterday ';
$lang->bug->yesterdayConfirmed = 'Bug Confirmed Yesterday ';
+1
View File
@@ -133,6 +133,7 @@ $lang->bug->overdueBugs = 'Retard';
$lang->bug->allBugs = 'Tous';
$lang->bug->byQuery = 'Rechercher';
$lang->bug->needConfirm = 'Story Changée';
$lang->bug->allProject = 'All Projects';
$lang->bug->allProduct = 'Tous les ' . $lang->productCommon . 's';
$lang->bug->my = 'Mes';
$lang->bug->yesterdayResolved = 'Bugs Résolus Hier ';
+1
View File
@@ -133,6 +133,7 @@ $lang->bug->overdueBugs = 'Quá hạn';
$lang->bug->allBugs = 'Tất cả Bugs';
$lang->bug->byQuery = 'Tìm kiếm';
$lang->bug->needConfirm = 'Câu chuyện đã thay đổi';
$lang->bug->allProject = 'All Projects';
$lang->bug->allProduct = 'All' . $lang->productCommon;
$lang->bug->my = 'Của bạn';
$lang->bug->yesterdayResolved = 'Giải quyết hôm qua ';
+1
View File
@@ -140,6 +140,7 @@ $lang->bug->overdueBugs = '过期Bug';
$lang->bug->allBugs = '所有';
$lang->bug->byQuery = '搜索';
$lang->bug->needConfirm = "{$lang->SRCommon}变动";
$lang->bug->allProject = '所有项目';
$lang->bug->allProduct = '所有' . $lang->productCommon;
$lang->bug->my = '我的';
$lang->bug->yesterdayResolved = '昨天解决Bug数';
+1
View File
@@ -140,6 +140,7 @@ $lang->bug->overdueBugs = '過期Bug';
$lang->bug->allBugs = '所有';
$lang->bug->byQuery = '搜索';
$lang->bug->needConfirm = "{$lang->SRCommon}變動";
$lang->bug->allProject = '所有項目';
$lang->bug->allProduct = '所有' . $lang->productCommon;
$lang->bug->my = '我的';
$lang->bug->yesterdayResolved = '昨天解決Bug數';
+46 -1
View File
@@ -1293,6 +1293,8 @@ class bugModel extends model
$projectID = $this->lang->navGroup->bug == 'qa' ? 0 : $this->session->project;
$productParams = ($productID and isset($products[$productID])) ? array($productID => $products[$productID]) : $products;
$productParams = $productParams + array('all' => $this->lang->bug->allProduct);
$projectParams = $this->getProjects($productID);
$projectParams = $projectParams + array('all' => $this->lang->bug->allProject);
/* Get all modules. */
$modules = array();
@@ -1305,6 +1307,7 @@ class bugModel extends model
$this->config->bug->search['actionURL'] = $actionURL;
$this->config->bug->search['queryID'] = $queryID;
if($this->config->systemMode == 'new') $this->config->bug->search['params']['project']['values'] = $projectParams;
$this->config->bug->search['params']['product']['values'] = $productParams;
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs($productID);
$this->config->bug->search['params']['module']['values'] = $modules;
@@ -1320,7 +1323,7 @@ class bugModel extends model
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') + array('all' => $this->lang->branch->all);
$this->config->bug->search['params']['branch']['values'] = array('' => '', 0 => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
@@ -2497,6 +2500,15 @@ class bugModel extends model
if($branch and strpos($bugQuery, '`branch` =') === false) $bugQuery .= " AND `branch` in('0','$branch')";
if(strpos($bugQuery, $allBranch) !== false) $bugQuery = str_replace($allBranch, '1', $bugQuery);
$allProject = "`project` = 'all'";
if(strpos($bugQuery, $allProject) !== false)
{
$projectIDList = $this->getAllProjectIds();
if(is_array($projectIDList)) $projectIDList = implode(',', $projectIDList);
$bugQuery = str_replace($allProject, '1', $bugQuery);
$bugQuery = $bugQuery . ' AND `project` in (' . $projectIDList . ')';
}
/* Fix bug #2878. */
if(strpos($bugQuery, ' `resolvedDate` ') !== false) $bugQuery = str_replace(' `resolvedDate` ', " `resolvedDate` != '0000-00-00 00:00:00' AND `resolvedDate` ", $bugQuery);
if(strpos($bugQuery, ' `closedDate` ') !== false) $bugQuery = str_replace(' `closedDate` ', " `closedDate` != '0000-00-00 00:00:00' AND `closedDate` ", $bugQuery);
@@ -2958,4 +2970,37 @@ class bugModel extends model
return sprintf($this->lang->bug->summary, count($bugs), $unresolved);
}
/**
* Get project list.
*
* @param int $productID
* @access public
* @return array
*/
public function getProjects($productID)
{
return $this->dao->select('t1.id,t1.name')
->from(TABLE_PROJECT)->alias('t1')
->leftjoin(TABLE_PROJECTPRODUCT)->alias('t2')->on('t1.id = t2.project')
->where('t1.type')->eq('project')
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.product')->eq($productID)
->fetchPairs();
}
/**
* Get ID list of all projects.
*
* @access public
* @return array
*/
public function getAllProjectIds()
{
return $this->dao->select('id')
->from(TABLE_PROJECT)
->where('deleted')->eq(0)
->andWhere('type')->eq('project')
->fetchPairs('id');
}
}
+13 -12
View File
@@ -402,18 +402,19 @@ $lang->pasteImgFail = "Failed to paste images. Try again later.";
$lang->pasteImgUploading = "Uploading...";
/* Time formats settings. */
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_MONTHTIME1'))define('DT_MONTHTIME1', 'n/d H:i');
if(!defined('DT_MONTHTIME2'))define('DT_MONTHTIME2', 'n/d H:i');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y/m/d');
if(!defined('DT_DATE4')) define('DT_DATE4', 'M d');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i');
if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n/d H:i');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y/m/d');
if(!defined('DT_DATE4')) define('DT_DATE4', 'M d');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('BRANCH_MAIN')) define('BRANCH_MAIN', '0');
/* Datepicker. */
$lang->datepicker = new stdclass();
+1 -1
View File
@@ -159,7 +159,7 @@ $lang->product->menu->plan = array('link' => "{$lang->productplan->shortComm
$lang->product->menu->release = array('link' => "{$lang->release->common}|release|browse|productID=%s", 'subModule' => 'release');
$lang->product->menu->roadmap = array('link' => "{$lang->roadmap}|product|roadmap|productID=%s");
if($config->systemMode == 'new') $lang->product->menu->project = array('link' => "{$lang->project->common}|product|project|status=all&productID=%s");
if($config->systemMode == 'classic') $lang->product->menu->project = array('link' => "{$lang->execution->common}|product|project|status=all&productID=%s");
if($config->systemMode == 'classic') $lang->product->menu->project = array('link' => "{$lang->execution->common}|product|project|status=all&productID=%s");
$lang->product->menu->track = array('link' => "{$lang->track}|story|track|productID=%s");
$lang->product->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=product&objectID=%s", 'subModule' => 'doc');
$lang->product->menu->dynamic = array('link' => "{$lang->dynamic}|product|dynamic|productID=%s");
+11 -10
View File
@@ -402,18 +402,19 @@ $lang->pasteImgFail = "贴图失败,请稍后重试。";
$lang->pasteImgUploading = "正在上传图片,请稍后...";
/* 时间格式设置。*/
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s');
if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i');
if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i');
if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n月d日 H:i');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日');
if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d');
if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd');
if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日');
if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日');
if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n');
if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s');
if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i');
if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31');
if(!defined('BRANCH_MAIN')) define('BRANCH_MAIN', '0');
/* datepicker 时间*/
$lang->datepicker = new stdclass();
+1 -1
View File
@@ -45,7 +45,7 @@ function deleteFile(fileID)
function fullScreen()
{
var element = document.getElementById('content');
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen;
if(requestMethod)
{
var afterEnterFullscreen = function()
+16
View File
@@ -1342,6 +1342,18 @@ class execution extends control
{
$this->lang->execution->type = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->execution->type);
}
$this->loadModel('user');
$poUsers = $this->user->getPairs('noclosed|nodeleted|pofirst', '', $this->config->maxCount);
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["PM"] = $this->config->user->moreLink;
$pmUsers = $this->user->getPairs('noclosed|nodeleted|pmfirst', '', $this->config->maxCount);
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["PO"] = $this->config->user->moreLink;
$qdUsers = $this->user->getPairs('noclosed|nodeleted|qdfirst', '', $this->config->maxCount);
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["QD"] = $this->config->user->moreLink;
$rdUsers = $this->user->getPairs('noclosed|nodeleted|devfirst', '', $this->config->maxCount);
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["RD"] = $this->config->user->moreLink;
$this->view->title = (($this->app->tab == 'execution') and ($this->config->systemMode == 'new')) ? $this->lang->execution->createExec : $this->lang->execution->create;
$this->view->position[] = $this->view->title;
@@ -1365,6 +1377,10 @@ class execution extends control
$this->view->whitelist = $whitelist;
$this->view->copyExecutionID = $copyExecutionID;
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$this->view->poUsers = $poUsers;
$this->view->pmUsers = $pmUsers;
$this->view->qdUsers = $qdUsers;
$this->view->rdUsers = $rdUsers;
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed');
$this->view->from = $this->app->tab;
$this->display();
+5 -5
View File
@@ -32,9 +32,9 @@ $(function()
/* Get checked stories. */
$('#batchToTaskButton').on('click', function()
{
var storyIdList = '';
linedTaskIdList = '';
unlinTaskIdList = '';
storyIdList = '';
linedTaskIdList = '';
unlinkTaskIdList = '';
$("input[name^='storyIdList']:checked").each(function()
{
if(linkedTaskStories[$(this).val()])
@@ -43,7 +43,7 @@ $(function()
}
else
{
unlinTaskIdList += $(this).val() + ',';
unlinkTaskIdList += $(this).val() + ',';
}
storyIdList += $(this).val() + ',';
});
@@ -60,7 +60,7 @@ $(function()
}
else
{
$('#storyIdList').val(unlinTaskIdList);
$('#storyIdList').val(unlinkTaskIdList);
}
}
else
+4
View File
@@ -388,6 +388,10 @@ class executionModel extends model
/* Set team of execution. */
$members = isset($_POST['teamMembers']) ? $_POST['teamMembers'] : array();
array_push($members, $sprint->PO, $sprint->QD, $sprint->PM, $sprint->RD);
$members = array_unique($members);
$member = array_values($members);
$roles = $this->loadModel('user')->getUserRoles(array_values($members));
foreach($members as $account)
{
+29
View File
@@ -152,6 +152,35 @@
<th><?php echo $lang->execution->copyTeam;?></th>
<td><?php echo html::select('teams', $teams, $copyExecutionID, "class='form-control chosen' data-placeholder='{$lang->execution->copyTeamTip}'"); ?></td>
</tr>
<tr>
<th rowspan='2'><?php echo $lang->execution->owner;?></th>
<td>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->execution->PO;?></span>
<?php echo html::select('PO', $poUsers, '', "class='form-control chosen'");?>
</div>
</td>
<td>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->execution->QD;?></span>
<?php echo html::select('QD', $qdUsers, '', "class='form-control chosen'");?>
</div>
</td>
</tr>
<tr>
<td>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->execution->PM;?></span>
<?php echo html::select('PM', $pmUsers, '', "class='form-control chosen'");?>
</div>
</td>
<td>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->execution->RD;?></span>
<?php echo html::select('RD', $rdUsers, '', "class='form-control chosen'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->execution->team;?></th>
<td colspan='3'><?php echo html::select('teamMembers[]', $users, '', "class='form-control chosen' multiple"); ?></td>
+2 -1
View File
@@ -152,7 +152,8 @@
if(viewType === 'doc' && (link.params.from === 'product' || link.params.$5 == 'product')) return 'product';
if(viewType === 'doc' && (link.params.from === 'project' || link.params.$5 == 'project')) return 'project';
if(viewType === 'doc') return 'doc';
if(viewType === 'doc') return 'doc';
if(viewType === 'story') return 'product';
}
else if(methodLowerCase === 'browsetask')
{
+1 -1
View File
@@ -858,7 +858,7 @@ class productModel extends model
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') + array('all' => $this->lang->branch->all);
$this->config->product->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
+20 -3
View File
@@ -78,9 +78,10 @@ class productplan extends control
$this->view->position[] = $this->lang->productplan->common;
$this->view->position[] = $this->lang->productplan->create;
$this->view->lastPlan = $lastPlan;
$this->view->branch = $branchID;
$this->view->parent = $parent;
$this->view->productID = $productID;
$this->view->lastPlan = $lastPlan;
$this->view->branch = $branchID;
$this->view->parent = $parent;
$this->display();
}
@@ -632,4 +633,20 @@ class productplan extends control
foreach($this->post->unlinkBugs as $bugID) $this->productplan->unlinkBug($bugID);
die(js::locate($this->createLink('productplan', 'view', "planID=$planID&type=bug&orderBy=$orderBy"), 'parent'));
}
/**
* AJAX: Get last plan.
*
* @param int $productID
* @param int $branch
* @param int $parent
* @access public
* @return object
*/
public function ajaxGetLast($productID, $branch = 0, $parent = 0)
{
$lastPlan = $this->productplan->getLast($productID, $branch, $parent);
echo json_encode($lastPlan);
}
}
+12
View File
@@ -62,3 +62,15 @@ $('#future').on('change', function()
$('#end').removeAttr('disabled').parents('tr').show();
}
});
$('#branch').change(function()
{
var branchID = $(this).val();
var link = createLink('productplan', 'ajaxGetLast', "productID=" + productID + "&branch=" + branchID);
$.post(link, function(data)
{
data = JSON.parse(data);
if(data) $('#title').parent().next('td').html('(' + lastLang + ': ' + data.title + ')');
})
})
+1 -1
View File
@@ -60,7 +60,7 @@ class productplanModel extends model
->beginIF($parent > 0)->andWhere('parent')->eq((int)$parent)->fi()
->andWhere('product')->eq((int)$productID)
->andWhere('end')->ne('2030-01-01')
->beginIF($branch)->andWhere('branch')->eq($branch)->fi()
->andWhere('branch')->eq($branch)
->orderBy('end desc')
->limit(1)
->fetch();
+2
View File
@@ -13,6 +13,8 @@
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::set('weekend', $config->execution->weekend);?>
<?php js::set('productID', $productID);?>
<?php js::set('lastLang', $lang->productplan->last);?>
<?php js::import($jsRoot . 'misc/date.js');?>
<div id='mainContent'class='main-content'>
<div class='center-block'>
+10 -2
View File
@@ -11,7 +11,7 @@ $config->project->editor->activate = array('id' => 'comment', 'tools' => 'simple
$config->project->editor->view = array('id' => 'lastComment', 'tools' => 'simpleTools');
$config->project->list = new stdclass();
$config->project->list->exportFields = 'id,parent,name,linkedProducts,status,begin,end,budget,PM,end,desc';
$config->project->list->exportFields = 'id,parent,code,name,linkedProducts,status,begin,end,budget,PM,end,desc';
$config->project->create = new stdclass();
$config->project->edit = new stdclass();
@@ -27,7 +27,7 @@ $config->project->sortFields->budget = 'budget';
global $lang;
$config->project->datatable = new stdclass();
$config->project->datatable->defaultField = array('id', 'name', 'PM', 'status', 'begin', 'end', 'budget', 'teamCount','estimate','consume', 'progress', 'actions');
$config->project->datatable->defaultField = array('id', 'name', 'code', 'PM', 'status', 'begin', 'end', 'budget', 'teamCount','estimate','consume', 'progress', 'actions');
$config->project->datatable->fieldList['id']['title'] = 'ID';
$config->project->datatable->fieldList['id']['fixed'] = 'left';
@@ -43,6 +43,14 @@ $config->project->datatable->fieldList['name']['required'] = 'yes';
$config->project->datatable->fieldList['name']['sort'] = 'no';
$config->project->datatable->fieldList['name']['pri'] = '1';
$config->project->datatable->fieldList['code']['title'] = 'code';
$config->project->datatable->fieldList['code']['fixed'] = 'left';
$config->project->datatable->fieldList['code']['width'] = '100';
$config->project->datatable->fieldList['code']['minWidth'] = '180';
$config->project->datatable->fieldList['code']['required'] = 'no';
$config->project->datatable->fieldList['code']['sort'] = 'no';
$config->project->datatable->fieldList['code']['pri'] = '1';
$config->project->datatable->fieldList['PM']['title'] = 'PM';
$config->project->datatable->fieldList['PM']['fixed'] = 'no';
$config->project->datatable->fieldList['PM']['width'] = '80';
+1 -1
View File
@@ -272,7 +272,7 @@ class project extends control
$this->view->title = $this->lang->project->browse;
$this->view->position[] = $this->lang->project->browse;
$this->view->projectStats = $projectStats;
$this->view->pager = $pager;
$this->view->programID = $programID;
+3
View File
@@ -1491,6 +1491,9 @@ class projectModel extends model
if(!empty($suffix)) echo $suffix;
if(!empty($suffix) || !empty($prefix)) echo '</div>';
break;
case 'code':
echo $project->code;
break;
case 'PM':
$user = $this->loadModel('user')->getByID($project->PM, 'account');
$userID = !empty($user) ? $user->id : '';
+1 -1
View File
@@ -91,7 +91,7 @@
$useDatatable = !commonModel::isTutorialMode() and (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable');
$setting = $this->datatable->getSetting('project');
$fixedFieldsWidth = $this->datatable->setFixedFieldWidth($setting);
if($useDatatable) include '../../common/view/datatable.html.php';
?>
<?php if(!$useDatatable) echo '<div class="table-responsive">';?>
+2 -2
View File
@@ -1474,7 +1474,7 @@ class story extends control
if(dao::isError()) die(js::error(dao::getError()));
foreach($allChanges as $storyID => $changes)
{
$actionID = $this->action->create('story', $storyID, 'Edited');
$actionID = $this->action->create('story', $storyID, 'Assigned', '', $this->post->assignedTo);
$this->action->logHistory($actionID, $changes);
}
}
@@ -2039,7 +2039,7 @@ class story extends control
$relatedStories = $this->dao->select('id,title')->from(TABLE_STORY) ->where('id')->in($relatedStoryIdList)->fetchPairs();
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('story')->andWhere('objectID')->in($storyIdList)->andWhere('extra')->ne('editor')->fetchGroup('objectID');
$relatedSpecs = $this->dao->select('*')->from(TABLE_STORYSPEC)->where('`story`')->in($storyIdList)->orderBy('version desc')->fetchGroup('story');
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedModules = $this->loadModel('tree')->getAllModulePairs();
foreach($stories as $story)
+7 -2
View File
@@ -1863,6 +1863,8 @@ class storyModel extends model
$story->assignedDate = $now;
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq((int)$storyID)->exec();
$allChanges[$storyID] = common::createChanges($oldStory, $story);
}
return $allChanges;
}
@@ -2413,6 +2415,7 @@ class storyModel extends model
$storyQuery = $storyQuery . ' AND `product` ' . helper::dbIN(array_keys($products));
if($excludeStories) $storyQuery = $storyQuery . ' AND `id` NOT ' . helper::dbIN($excludeStories);
if($this->app->moduleName == 'productplan') $storyQuery .= " AND `status` NOT IN ('closed') AND `parent` >= 0 ";
$allBranch = "`branch` = 'all'";
if($executionID != '')
{
foreach($products as $product) $branches[$product->branch] = $product->branch;
@@ -2430,9 +2433,11 @@ class storyModel extends model
}
elseif($branch)
{
$allBranch = "`branch` = 'all'";
if($branch and strpos($storyQuery, '`branch` =') === false) $storyQuery .= " AND `branch` in('0','$branch')";
if(strpos($storyQuery, $allBranch) !== false) $storyQuery = str_replace($allBranch, '1', $storyQuery);
}
elseif(strpos($storyQuery, $allBranch) !== false)
{
$storyQuery = str_replace($allBranch, '1', $storyQuery);
}
$storyQuery = preg_replace("/`plan` +LIKE +'%([0-9]+)%'/i", "CONCAT(',', `plan`, ',') LIKE '%,$1,%'", $storyQuery);
+1
View File
@@ -453,6 +453,7 @@ class testcase extends control
$this->view->title = $title;
$this->view->position = $position;
$this->view->projectID = isset($projectID) ? $projectID : '';
$this->view->productID = $productID;
$this->view->productName = $this->products[$productID];
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $branch);
+9 -1
View File
@@ -124,7 +124,15 @@ function setStories()
productID = $('#product').val();
branch = $('#branch').val();
if(typeof(branch) == 'undefined') branch = 0;
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID=0&onlyOption=false&status=noclosed&limit=50');
if(tab == 'execution')
{
link = createLink('story', 'ajaxGetExecutionStories', 'executionID=' + executionID + '&productID=' + productID + '&branch' + branch + '&moduleID=' + moduleID + '&storyID=0');
}
else
{
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID=0&onlyOption=false&status=noclosed&limit=50');
}
$.get(link, function(stories)
{
var value = $('#story').val();
+1 -1
View File
@@ -1439,7 +1439,7 @@ class testcaseModel extends model
else
{
$this->config->testcase->search['fields']['branch'] = $this->lang->product->branch;
$this->config->testcase->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
$this->config->testcase->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']);
$this->config->testcase->search['actionURL'] = $actionURL;
+2
View File
@@ -16,6 +16,8 @@
<?php js::set('lblBefore', $lang->testcase->insertBefore);?>
<?php js::set('lblAfter', $lang->testcase->insertAfter);?>
<?php js::set('isonlybody', isonlybody());?>
<?php js::set('executionID', $projectID);?>
<?php js::set('tab', $this->app->tab);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
+1 -1
View File
@@ -42,7 +42,7 @@ class testsuiteModel extends model
if($currentProduct->type != 'normal')
{
$this->app->loadLang('branch');
$branchName = $this->lang->branch->all . $this->lang->product->branchName[$currentProduct->type];
$branchName = $this->lang->branch->main;
$output .= "<div class='btn-group'><button id='currentBranch' type='button' class='btn btn-limit'>{$branchName} </button></div></div>";
}
$output .= '</div>';
-1
View File
@@ -119,7 +119,6 @@ $(function()
{
$('#root').change(function()
{
if($(this).val() == currentRoot) return true;
var confirmRoot = <?php echo json_encode($type == 'doc' ? $lang->tree->confirmRoot4Doc : $lang->tree->confirmRoot);?>;
if(!confirm(confirmRoot))
{
+4
View File
@@ -729,6 +729,10 @@ class upgradeModel extends model
$this->saveLogs('Execute 15_7');
$this->execSQL($this->getUpgradeFile('15.7'));
$this->appendExec('15_7');
case '15_7_1':
$this->saveLogs('Execute 15_7_1');
$this->execSQL($this->getUpgradeFile('15.7.1'));
$this->appendExec('15_7_1');
}
$this->deletePatch();
+12 -6
View File
@@ -871,13 +871,19 @@ $(document).ready(function()
$(document).on('click', '#helpMenuItem .close-help-tab', function(){$('#helpMenuItem').prev().remove();$('#helpMenuItem').remove();});
$(document).keydown(function(event)
/* Open link in new tab when pressed ctrl key in windows */
if(window.navigator.userAgent.match(/Windows/i))
{
if(event.ctrlKey) $('a').attr('target', '_blank');
}).keyup(function()
{
$('a').attr('target', '');
});
$(document).on('mousedown', 'a', function(e)
{
var $a = $(this);
if(!e.ctrlKey || $a.attr('target')) return;
$a.attr('target', '_blank');
clearTimeout($a.data('ctrlTimer'));
$a.data('ctrlTimer', setTimeout(function(){$a.attr('target', null).data('ctrlTimer', 0)}, 100));
e.preventDefault();
});
}
/* Hide the global create drop-down when hovering over the avatar. */
$('.has-avatar').hover(function()