Merge branch 'master' into zenops_46
This commit is contained in:
@@ -734,10 +734,13 @@ class baseRouter
|
||||
$account = $sql->quote($account);
|
||||
$vision = $this->dbh->query("SELECT * FROM " . TABLE_CONFIG . " WHERE owner = $account AND `key` = 'vision' LIMIT 1")->fetch();
|
||||
if($vision) $vision = $vision->value;
|
||||
if(empty($vision))
|
||||
|
||||
$user = $this->dbh->query("SELECT * FROM " . TABLE_USER . " WHERE account = $account AND deleted = '0' LIMIT 1")->fetch();
|
||||
if(!empty($user->visions))
|
||||
{
|
||||
$user = $this->dbh->query("SELECT * FROM " . TABLE_USER . " WHERE account = $account AND deleted = '0' LIMIT 1")->fetch();
|
||||
if(!empty($user->visions)) list($vision) = explode(',', $user->visions);
|
||||
$userVisions = explode(',', $user->visions);
|
||||
if(!in_array($vision, $userVisions)) $vision = '';
|
||||
if(empty($vision)) list($vision) = $userVisions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@ class zfile
|
||||
* @param bool $logLevel
|
||||
* @param string $logFile
|
||||
* @param array $excludeFiles
|
||||
* @param bool $toIsLink
|
||||
* @access public
|
||||
* @return array copied files, count, size or message.
|
||||
*/
|
||||
public function copyDir($from, $to, $logLevel = false, $logFile = '', $excludeFiles = array())
|
||||
public function copyDir($from, $to, $logLevel = false, $logFile = '', $excludeFiles = array(), $toIsLink = false)
|
||||
{
|
||||
static $copiedFiles = array();
|
||||
static $errorFiles = array();
|
||||
@@ -42,7 +43,16 @@ class zfile
|
||||
if(!empty($log['message'])) return $log;
|
||||
|
||||
$from = realpath($from) . '/';
|
||||
$to = realpath($to) . '/';
|
||||
if(is_link($to) || $toIsLink)
|
||||
{
|
||||
$to = $to . '/';
|
||||
|
||||
$toIsLink = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$to = realpath($to) . '/';
|
||||
}
|
||||
|
||||
$entries = scandir($from);
|
||||
foreach($entries as $entry)
|
||||
@@ -83,7 +93,7 @@ class zfile
|
||||
{
|
||||
$nextFrom = $fullEntry;
|
||||
$nextTo = $to . $entry;
|
||||
$result = $this->copyDir($nextFrom, $nextTo, $logLevel, $logFile);
|
||||
$result = $this->copyDir($nextFrom, $nextTo, $logLevel, $logFile, array(), $toIsLink);
|
||||
$count += $result['count'];
|
||||
$size += $result['size'];
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ $lang->action->desc->resume = '$date, the execution node is resume
|
||||
$lang->action->desc->reboot = '$date, the execution node is reboot by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->destroy = '$date, the execution node is destroyed by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->switchtolight = '$date, Switch from ALM mode to light mode by <strong>'. $lang->admin->system .'</strong>.' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the sprints of the project from the $extra.' . "\n";
|
||||
$lang->action->desc->getvnc = '$date, Remote control <strong>$extra</strong> by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the ' . $lang->executionCommon . 's of the project from the $extra.' . "\n";
|
||||
|
||||
/* Used to describe the history of operations related to parent-child tasks. */
|
||||
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
|
||||
|
||||
@@ -232,8 +232,8 @@ $lang->action->desc->resume = '$date, the execution node is resume
|
||||
$lang->action->desc->reboot = '$date, the execution node is reboot by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->destroy = '$date, the execution node is destroyed by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->switchtolight = '$date, Switch from ALM mode to light mode by <strong>'. $lang->admin->system .'</strong>.' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the sprints of the project from the $extra.' . "\n";
|
||||
$lang->action->desc->getvnc = '$date, Remote control <strong>$extra</strong> by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the ' . $lang->executionCommon . 's of the project from the $extra.' . "\n";
|
||||
|
||||
/* Used to describe the history of operations related to parent-child tasks. */
|
||||
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
|
||||
|
||||
@@ -232,8 +232,8 @@ $lang->action->desc->resume = '$date, the execution node is resume
|
||||
$lang->action->desc->reboot = '$date, the execution node is reboot by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->destroy = '$date, the execution node is destroyed by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->switchtolight = '$date, Switch from ALM mode to light mode by <strong>'. $lang->admin->system .'</strong>.' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the sprints of the project from the $extra.' . "\n";
|
||||
$lang->action->desc->getvnc = '$date, Remote control <strong>$extra</strong> by <strong>$actor</strong> .' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the ' . $lang->executionCommon . 's of the project from the $extra.' . "\n";
|
||||
|
||||
/* Used to describe the history of operations related to parent-child tasks. */
|
||||
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> a créé un sous-tâche <strong>$extra</strong>。' . "\n";
|
||||
|
||||
@@ -232,8 +232,8 @@ $lang->action->desc->resume = '$date, 由 <strong>$actor</strong>
|
||||
$lang->action->desc->reboot = '$date, 由 <strong>$actor</strong> 重启。' . "\n";
|
||||
$lang->action->desc->destroy = '$date, 由 <strong>$actor</strong> 销毁。' . "\n";
|
||||
$lang->action->desc->switchtolight = '$date, 由于 <strong>'. $lang->admin->system .'</strong> 从全生命周期管理模式切换为轻量管理模式,项目访问控制由项目集内公开调整为私有。' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, 系统判断由于迭代所属项目与$extra取消关联,同步将迭代与$extra取消关联。' . "\n";
|
||||
$lang->action->desc->getvnc = '$date, <strong>$actor</strong>对执行节点 <strong>$extra</strong> 进行了远程操控。' . "\n";
|
||||
$lang->action->desc->unlinkproduct = '$date, 系统判断由于' . $lang->executionCommon . '所属项目与$extra取消关联,同步将' . $lang->executionCommon . '与$extra取消关联。' . "\n";
|
||||
|
||||
/* 用来描述和父子任务相关的操作历史记录。*/
|
||||
$lang->action->desc->createchildren = '$date, 由 <strong>$actor</strong> 创建子任务 <strong>$extra</strong>。' . "\n";
|
||||
|
||||
@@ -141,3 +141,4 @@ $lang->admin->safe->resetPWDList[0] = 'Off';
|
||||
$lang->admin->safe->noticeMode = 'The password will be checked when creating and modifying user information, and changing passwords.';
|
||||
$lang->admin->safe->noticeWeakMode = 'The password will be checked when logging into the system, creating and modifying user information, and changing passwords.';
|
||||
$lang->admin->safe->noticeStrong = 'The longer the password, the more letters, numbers, or special characters it contains, and the less repetitive the password, the more secure it is!';
|
||||
$lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.';
|
||||
|
||||
@@ -141,3 +141,4 @@ $lang->admin->safe->resetPWDList[0] = 'Off';
|
||||
$lang->admin->safe->noticeMode = 'The password will be checked when creating and modifying user information, and changing passwords.';
|
||||
$lang->admin->safe->noticeWeakMode = 'The password will be checked when logging into the system, creating and modifying user information, and changing passwords.';
|
||||
$lang->admin->safe->noticeStrong = 'The longer the password, the more letters, numbers, or special characters it contains, and the less repetitive the password, the more secure it is!';
|
||||
$lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.';
|
||||
@@ -141,3 +141,4 @@ $lang->admin->safe->resetPWDList[0] = 'Off';
|
||||
$lang->admin->safe->noticeMode = "Le mot de passe sera vérifié lors de la création et de la modification des coordonnées de l'utilisateur, et du changement de mot de passe.";
|
||||
$lang->admin->safe->noticeWeakMode = "Le mot de passe sera vérifié lors de la connexion au système, de la création et de la modification des coordonnées de l'utilisateur, et du changement de mot de passe.";
|
||||
$lang->admin->safe->noticeStrong = "Le mot de passe est d'autant plus sécurisé qu'il est long, qu'il contient plus de lettres, de chiffres ou de caractères spéciaux, et que les lettres du mot de passe sont peu répétitives !";
|
||||
$lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.';
|
||||
|
||||
@@ -84,3 +84,4 @@ $lang->admin->safe->loginCaptchaList[0] = 'No';
|
||||
|
||||
$lang->admin->safe->noticeMode = 'Mật khẩu sẽ được kiểm tra khi người dùng đăng nhập hoặc người dùng thêm hoặc sửa.';
|
||||
$lang->admin->safe->noticeStrong = '';
|
||||
$lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.';
|
||||
@@ -141,3 +141,4 @@ $lang->admin->safe->resetPWDList[0] = '关闭';
|
||||
$lang->admin->safe->noticeMode = '系统会在创建和修改用户、修改密码的时候检查用户口令。';
|
||||
$lang->admin->safe->noticeWeakMode = '系统会在登录、创建和修改用户、修改密码的时候检查用户口令。';
|
||||
$lang->admin->safe->noticeStrong = '密码长度越长,含有大写字母或数字或特殊符号越多,密码字母越不重复,安全度越强!';
|
||||
$lang->admin->safe->noticeGd = '系统检测到您的服务器未安装GD模块,无法使用验证码功能,请安装后使用。';
|
||||
|
||||
@@ -82,5 +82,7 @@ $lang->admin->safe->modifyPasswordList[0] = '不強制';
|
||||
$lang->admin->safe->loginCaptchaList[1] = '是';
|
||||
$lang->admin->safe->loginCaptchaList[0] = '否';
|
||||
|
||||
$lang->admin->safe->noticeMode = '系統會在登錄、創建和修改用戶、修改密碼的時候檢查用戶口令。';
|
||||
$lang->admin->safe->noticeStrong = '密碼長度越長,含有大寫字母或數字或特殊符號越多,密碼字母越不重複,安全度越強!';
|
||||
$lang->admin->safe->noticeMode = '系統會在創建和修改用戶、修改密碼的時候檢查用戶口令。';
|
||||
$lang->admin->safe->noticeWeakMode = '系統會在登錄、創建和修改用戶、修改密碼的時候檢查用戶口令。';
|
||||
$lang->admin->safe->noticeStrong = '密碼長度越長,含有大寫字母或數字或特殊符號越多,密碼字母越不重複,安全度越強!';
|
||||
$lang->admin->safe->noticeGd = '系統檢測到您的伺服器未安裝GD模組,無法使用驗證碼功能,請安裝後使用。';
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
.notice {color:#2667E3; margin-left: 12px;}
|
||||
</style>
|
||||
<?php js::set('adminLang', $lang->admin);?>
|
||||
<?php js::set('loadedGD', extension_loaded('gd'));?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
@@ -71,7 +72,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->admin->safe->loginCaptcha?></th>
|
||||
<td colspan='2'><?php echo html::radio('loginCaptcha', $lang->admin->safe->loginCaptchaList, isset($config->safe->loginCaptcha) ? $config->safe->loginCaptcha : 0)?></td>
|
||||
<td><?php echo html::radio('loginCaptcha', $lang->admin->safe->loginCaptchaList, isset($config->safe->loginCaptcha) ? $config->safe->loginCaptcha : 0)?></td>
|
||||
<td class='notice'><?php if(!extension_loaded('gd')) echo $lang->admin->safe->noticeGd;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='3' class='text-center form-actions'>
|
||||
@@ -89,6 +91,7 @@ $(function()
|
||||
{
|
||||
var mode = $("input[name='mode']:checked").val();
|
||||
showModeRule(mode);
|
||||
if(!loadedGD) $('#loginCaptcha1').attr('disabled', true);
|
||||
});
|
||||
function showModeRule(mode)
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<?php $code = $group . ucfirst($feature);?>
|
||||
<?php if(strpos(",$disabledFeatures,", ",$code,") !== false) continue;?>
|
||||
<?php $hasData = true;?>
|
||||
<?php endForeach;?>
|
||||
<?php endforeach;?>
|
||||
|
||||
<?php if($hasData):?>
|
||||
<tr>
|
||||
@@ -52,11 +52,11 @@
|
||||
<?php echo html::checkbox("module[{$code}]", array('1' => $lang->admin->setModule->{$feature}), $value, "data-code='{$code}'", 'inline');?>
|
||||
<?php echo html::hidden("module[{$code}][]", $value, $value ? 'disabled' : '');?>
|
||||
</div>
|
||||
<?php endForeach;?>
|
||||
<?php endforeach;?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php endForeach;?>
|
||||
<?php endforeach;?>
|
||||
<tr>
|
||||
<td class='text-middle text-right thWidth'>
|
||||
<div class="checkbox-primary checkbox-inline checkbox-right check-all">
|
||||
@@ -68,7 +68,7 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>`
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
<?php $isFirstTab = true;?>
|
||||
<?php $printMore = false;?>
|
||||
<?php $i = 0;?>
|
||||
<?php $maxItem = common::checkNotCN() ? 6 : 8;?>
|
||||
<?php foreach($hasViewPriv as $type => $bool):?>
|
||||
<?php if(!common::checkNotCN() or $i <= 6):?>
|
||||
<?php if($i <= $maxItem):?>
|
||||
<li<?php if($isFirstTab) {echo ' class="active"';}?>>
|
||||
<a data-tab href='#assigntomeTab-<?php echo $type;?>' onClick="changeLabel('<?php echo $type;?>')">
|
||||
<?php echo $type == 'review' ? $lang->my->audit : $lang->block->availableBlocks->$type;?>
|
||||
@@ -36,7 +37,7 @@
|
||||
<?php endif;?>
|
||||
<li<?php if($isFirstTab) {echo ' class="active"';}?>>
|
||||
<a data-tab href='#assigntomeTab-<?php echo $type;?>' class='<?php echo "$type"?>' onClick="changeMoreBtn('<?php echo $type;?>', this);">
|
||||
<?php echo $lang->block->availableBlocks->$type;?>
|
||||
<?php echo $type == 'review' ? $lang->my->audit : $lang->block->availableBlocks->$type;?>
|
||||
<span class='label label-light label-badge label-assignto <?php echo $type . "-count "; echo $isFirstTab ? '' : 'hidden'; $isFirstTab = false ?>'><?php echo $count[$type];?></span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -328,11 +328,13 @@ $config->bug->datatable->fieldList['os']['title'] = 'os';
|
||||
$config->bug->datatable->fieldList['os']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['os']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['os']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['os']['control'] = 'multiple';
|
||||
|
||||
$config->bug->datatable->fieldList['browser']['title'] = 'browser';
|
||||
$config->bug->datatable->fieldList['browser']['fixed'] = 'no';
|
||||
$config->bug->datatable->fieldList['browser']['width'] = '80';
|
||||
$config->bug->datatable->fieldList['browser']['required'] = 'no';
|
||||
$config->bug->datatable->fieldList['browser']['control'] = 'multiple';
|
||||
|
||||
$config->bug->datatable->fieldList['mailto']['title'] = 'mailto';
|
||||
$config->bug->datatable->fieldList['mailto']['fixed'] = 'no';
|
||||
|
||||
+39
-23
@@ -227,7 +227,8 @@ class bug extends control
|
||||
$this->view->product = $product;
|
||||
$this->view->projectProducts = $this->product->getProducts($this->projectID);
|
||||
$this->view->productName = $productName;
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'withreleased');
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $branch);
|
||||
$this->view->releasedBuilds = $this->loadModel('release')->getReleasedBuilds($productID, $branch);
|
||||
$this->view->modules = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
|
||||
$this->view->moduleTree = $moduleTree;
|
||||
$this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all;
|
||||
@@ -558,13 +559,13 @@ class bug extends control
|
||||
/* If executionID is setted, get builds and stories of this execution. */
|
||||
if($executionID)
|
||||
{
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noterminate,nodone', $executionID, 'execution');
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noterminate,nodone,noreleased', $executionID, 'execution');
|
||||
$stories = $this->story->getExecutionStoryPairs($executionID);
|
||||
if(!$projectID) $projectID = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch('project');
|
||||
}
|
||||
else
|
||||
{
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noterminate,nodone,withbranch');
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noterminate,nodone,withbranch,noreleased');
|
||||
$stories = $this->story->getProductStoryPairs($productID, $branch, 0, 'all','id_desc', 0, 'full', 'story', false);
|
||||
}
|
||||
|
||||
@@ -655,6 +656,7 @@ class bug extends control
|
||||
$this->view->projectExecutionPairs = $this->loadModel('project')->getProjectExecutionPairs();
|
||||
$this->view->executions = defined('TUTORIAL') ? $this->loadModel('tutorial')->getExecutionPairs() : $executions;
|
||||
$this->view->builds = $builds;
|
||||
$this->view->releasedBuilds = $this->loadModel('release')->getReleasedBuilds($productID, $branch);
|
||||
$this->view->moduleID = (int)$moduleID;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->projectModel = $projectModel;
|
||||
@@ -765,7 +767,7 @@ class bug extends control
|
||||
/* If executionID is setted, get builds and stories of this execution. */
|
||||
if($executionID)
|
||||
{
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty', $executionID, 'execution');
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noreleased', $executionID, 'execution');
|
||||
$stories = $this->story->getExecutionStoryPairs($executionID);
|
||||
$execution = $this->loadModel('execution')->getById($executionID);
|
||||
if($execution->type == 'kanban')
|
||||
@@ -785,7 +787,7 @@ class bug extends control
|
||||
}
|
||||
else
|
||||
{
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty');
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noreleased');
|
||||
$stories = $this->story->getProductStoryPairs($productID, $branch);
|
||||
}
|
||||
|
||||
@@ -933,7 +935,7 @@ class bug extends control
|
||||
$this->view->branchName = $product->type == 'normal' ? '' : zget($branches, $bug->branch, '');
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'withreleased');
|
||||
$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');
|
||||
@@ -1080,18 +1082,18 @@ class bug extends control
|
||||
$this->view->position[] = $this->lang->bug->edit;
|
||||
|
||||
/* Assign. */
|
||||
$allBuilds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,withreleased');
|
||||
$allBuilds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty');
|
||||
if($executionID)
|
||||
{
|
||||
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch', $executionID, 'execution');
|
||||
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch,noreleased', $executionID, 'execution');
|
||||
}
|
||||
elseif($projectID)
|
||||
{
|
||||
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch', $projectID, 'project');
|
||||
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch,noreleased', $projectID, 'project');
|
||||
}
|
||||
else
|
||||
{
|
||||
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch');
|
||||
$openedBuilds = $this->build->getBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone,withbranch,noreleased');
|
||||
}
|
||||
|
||||
/* Set the openedBuilds list. */
|
||||
@@ -1164,7 +1166,6 @@ class bug extends control
|
||||
if($product->shadow) $this->view->project = $this->loadModel('project')->getByShadowProduct($bug->product);
|
||||
|
||||
$this->view->bug = $bug;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->product = $product;
|
||||
$this->view->execution = $execution;
|
||||
$this->view->productBugs = $productBugs;
|
||||
@@ -1829,15 +1830,15 @@ class bug extends control
|
||||
$this->bug->checkBugExecutionPriv($bug);
|
||||
$this->qa->setMenu($this->products, $productID, $bug->branch);
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->resolve;
|
||||
$this->view->bug = $bug;
|
||||
$this->view->users = $users;
|
||||
$this->view->assignedTo = $assignedTo;
|
||||
$this->view->productBugs = $productBugs;
|
||||
$this->view->executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0, 'id_desc', $projectID, 'stagefilter');
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'withbranch');
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
$this->view->execution = isset($execution) ? $execution : '';
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->resolve;
|
||||
$this->view->bug = $bug;
|
||||
$this->view->users = $users;
|
||||
$this->view->assignedTo = $assignedTo;
|
||||
$this->view->productBugs = $productBugs;
|
||||
$this->view->executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0, 'id_desc', $projectID, 'stagefilter');
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'withbranch,noreleased');
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
$this->view->execution = isset($execution) ? $execution : '';
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -1934,7 +1935,7 @@ class bug extends control
|
||||
|
||||
$this->view->bug = $bug;
|
||||
$this->view->users = $this->user->getPairs('noclosed', $bug->resolvedBy);
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'noempty', 0, 'execution', $bug->openedBuild);
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'noempty,noreleased', 0, 'execution', $bug->openedBuild);
|
||||
$this->view->actions = $this->action->getList('bug', $bugID);
|
||||
|
||||
$this->display();
|
||||
@@ -2151,7 +2152,7 @@ class bug extends control
|
||||
|
||||
$this->view->bugs = $bugs;
|
||||
$this->view->users = $this->user->getPairs();
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty');
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noreleased');
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -2413,7 +2414,7 @@ class bug extends control
|
||||
public function ajaxGetBugFieldOptions($productID, $executionID = 0)
|
||||
{
|
||||
$modules = $this->loadModel('tree')->getOptionMenu($productID, 'bug');
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', '', $executionID, 'execution');
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noreleased', $executionID, 'execution');
|
||||
$type = $this->lang->bug->typeList;
|
||||
$pri = $this->lang->bug->priList;
|
||||
$severity = $this->lang->bug->severityList;
|
||||
@@ -2501,4 +2502,19 @@ class bug extends control
|
||||
if($project->model == 'kanban') return print($this->lang->bug->kanban);
|
||||
return print($this->lang->bug->execution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get released builds.
|
||||
*
|
||||
* @param int $productID
|
||||
* @param int|string $branch
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetReleasedBuilds($productID, $branch = 'all')
|
||||
{
|
||||
$releasedBuilds = $this->loadModel('release')->getReleasedBuilds($productID, $branch);
|
||||
|
||||
return print(helper::jsonEncode($releasedBuilds));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@ function setOpenedBuilds(link, index)
|
||||
var selected = $('#buildBox' + index).find('select').val();
|
||||
$('#buildBox' + index).html(builds);
|
||||
$('#buildBox' + index).find('select').val(selected);
|
||||
$('#openedBuilds' + index + '_chosen').remove();
|
||||
$('#pickerDropMenu-pk_openedBuild' + index).remove();
|
||||
$('#openedBuilds' + index).next('.picker').remove();
|
||||
$('#buildBox' + index + ' select').removeClass('select-3');
|
||||
$('#buildBox' + index + ' select').addClass('select-1');
|
||||
$('#buildBox' + index + ' select').attr('name','openedBuilds[' + index + '][]');
|
||||
$('#buildBox' + index + ' select').attr('id','openedBuilds' + index);
|
||||
$('#buildBox' + index + ' select').chosen();
|
||||
$('#buildBox' + index + ' select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
|
||||
index++;
|
||||
if($('#executions' + index).val() != 'ditto') break;
|
||||
|
||||
+99
-26
@@ -19,6 +19,27 @@ $(function()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if($('#openedBuild').length || $('#resolvedBuild').length || $('[name^=openedBuilds]').length)
|
||||
{
|
||||
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
|
||||
|
||||
$('#openedBuild, #resolvedBuild, [name^=openedBuilds]').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
}
|
||||
|
||||
function markReleasedBuilds($option)
|
||||
{
|
||||
var build = $option.attr('data-value');
|
||||
if($.inArray(build, releasedBuilds) != -1)
|
||||
{
|
||||
if(!$option.find('.label-released').length)
|
||||
{
|
||||
var optionText = $option.find('.picker-option-text').html();
|
||||
$option.find('.picker-option-text').replaceWith("<p class='picker-option-text no-margin'><span class='label label-released label-primary label-outline'>" + releasedBuild + "</span> " + optionText + "</p>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all fields.
|
||||
*
|
||||
@@ -178,6 +199,8 @@ function loadAllExecutionBuilds(executionID, productID, buildBox)
|
||||
{
|
||||
branch = $('#branch').val();
|
||||
if(typeof(branch) == 'undefined') branch = 0;
|
||||
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
|
||||
|
||||
if(page == 'create')
|
||||
{
|
||||
oldOpenedBuild = $('#openedBuild').val() ? $('#openedBuild').val() : 0;
|
||||
@@ -186,10 +209,10 @@ function loadAllExecutionBuilds(executionID, productID, buildBox)
|
||||
{
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control" multiple=multiple></select>';
|
||||
$('#openedBuild').replaceWith(data);
|
||||
$('#openedBuild_chosen').remove();
|
||||
$('#pickerDropMenu-pk_openedBuild').remove();
|
||||
$('#openedBuild').next('.picker').remove();
|
||||
$("#openedBuild").chosen();
|
||||
notice();
|
||||
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
})
|
||||
}
|
||||
if(page == 'edit')
|
||||
@@ -197,12 +220,12 @@ function loadAllExecutionBuilds(executionID, productID, buildBox)
|
||||
if(buildBox == 'openedBuildBox')
|
||||
{
|
||||
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&needCreate=true&type=all');
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').chosen()});
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
if(buildBox == 'resolvedBuildBox')
|
||||
{
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch + '&index=0&type=all');
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').chosen()});
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,6 +242,9 @@ function loadAllProductBuilds(productID, buildBox)
|
||||
{
|
||||
branch = $('#branch').val();
|
||||
if(typeof(branch) == 'undefined') branch = 0;
|
||||
|
||||
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
|
||||
|
||||
if(page == 'create')
|
||||
{
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&type=all');
|
||||
@@ -226,10 +252,10 @@ function loadAllProductBuilds(productID, buildBox)
|
||||
{
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control" multiple=multiple></select>';
|
||||
$('#openedBuild').replaceWith(data);
|
||||
$('#openedBuild_chosen').remove();
|
||||
$('#pickerDropMenu-pk_openedBuild').remove();
|
||||
$('#openedBuild').next('.picker').remove();
|
||||
$("#openedBuild").chosen();
|
||||
notice();
|
||||
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
})
|
||||
}
|
||||
if(page == 'edit')
|
||||
@@ -237,12 +263,12 @@ function loadAllProductBuilds(productID, buildBox)
|
||||
if(buildBox == 'openedBuildBox')
|
||||
{
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&type=all');
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').chosen()});
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
if(buildBox == 'resolvedBuildBox')
|
||||
{
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch + '&index=0&type=all');
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').chosen()});
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,7 +320,7 @@ function loadProductStories(productID)
|
||||
function loadProductProjects(productID)
|
||||
{
|
||||
required = $('#project_chosen').hasClass('required');
|
||||
branch = $('#branch').val();
|
||||
branch = $('#branch').val();
|
||||
if(typeof(branch) == 'undefined') branch = 0;
|
||||
link = createLink('product', 'ajaxGetProjects', 'productID=' + productID + '&branch=' + branch + '&projectID=' + oldProjectID);
|
||||
$('#projectBox').load(link, function()
|
||||
@@ -437,23 +463,25 @@ function loadProductBuilds(productID)
|
||||
if(typeof(oldOpenedBuild) == 'undefined') oldOpenedBuild = 0;
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch);
|
||||
|
||||
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
|
||||
|
||||
if(page == 'create')
|
||||
{
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control" multiple=multiple></select>';
|
||||
$('#openedBuild').replaceWith(data);
|
||||
$('#openedBuild_chosen').remove();
|
||||
$('#pickerDropMenu-pk_openedBuild').remove();
|
||||
$('#openedBuild').next('.picker').remove();
|
||||
$("#openedBuild").chosen();
|
||||
notice();
|
||||
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').chosen()});
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').chosen()});
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,9 +494,12 @@ function loadProductBuilds(productID)
|
||||
*/
|
||||
function loadExecutionRelated(executionID)
|
||||
{
|
||||
executionID = parseInt(executionID);
|
||||
executionID = parseInt(executionID);
|
||||
currentProjectID = $('#project').val() == 'undefined' ? 0 : $('#project').val();
|
||||
|
||||
if(executionID)
|
||||
{
|
||||
if(currentProjectID == 0) loadProjectByExecutionID(executionID);
|
||||
loadExecutionTasks(executionID);
|
||||
loadExecutionStories(executionID);
|
||||
loadExecutionBuilds(executionID);
|
||||
@@ -477,7 +508,6 @@ function loadExecutionRelated(executionID)
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentProjectID = $('#project').val() == 'undefined' ? 0 : $('#project').val();
|
||||
var currentProductID = $('#product').val();
|
||||
|
||||
$('#taskIdBox').innerHTML = '<select id="task"></select>'; // Reset the task.
|
||||
@@ -496,6 +526,43 @@ function loadExecutionRelated(executionID)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a project by execution id.
|
||||
*
|
||||
* @param executionID $executionID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function loadProjectByExecutionID(executionID)
|
||||
{
|
||||
link = createLink('project', 'ajaxGetPairsByExecution', 'executionID=' + executionID, 'json');
|
||||
required = $('#project_chosen').hasClass('required');
|
||||
productID = $('#product').val();
|
||||
|
||||
$.post(link, function(data)
|
||||
{
|
||||
var originProject = $('#project').html();
|
||||
|
||||
if($('#project').find('option[value="' + data.id + '"]').length > 0)
|
||||
{
|
||||
$('#project').find('option[value="' + data.id + '"]').attr('selected', 'selected');
|
||||
originProject = $('#project').html();
|
||||
$('#project').replaceWith('<select id="project" name="project" class="form-control" onchange="loadProductExecutions(' + productID + ', this.value)">' + originProject + '</select>');
|
||||
}
|
||||
else
|
||||
{
|
||||
var newProject = '<option value="' + data.id + '" data-keys="' + data.namePinyin + '" selected="selected">' + data.name + '</option>';
|
||||
$('#project').replaceWith('<select id="project" name="project" class="form-control" onchange="loadProductExecutions(' + productID + ', this.value)">' + originProject + newProject+ '</select>');
|
||||
}
|
||||
|
||||
$('#project_chosen').remove();
|
||||
$('#project').next('.picker').remove();
|
||||
$('#project').chosen();
|
||||
|
||||
if(required) $('#project_chosen').addClass('required');
|
||||
}, 'json')
|
||||
}
|
||||
|
||||
/**
|
||||
* Load execution tasks.
|
||||
*
|
||||
@@ -552,28 +619,30 @@ function loadProjectBuilds(projectID)
|
||||
var productID = $('#product').val();
|
||||
var oldOpenedBuild = $('#openedBuild').val() ? $('#openedBuild').val() : 0;
|
||||
|
||||
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
|
||||
|
||||
if(page == 'create')
|
||||
{
|
||||
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=&branch=' + branch);
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control" multiple=multiple></select>';
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control picker-select" multiple=multiple></select>';
|
||||
$('#openedBuild').replaceWith(data);
|
||||
$('#openedBuild').val(oldOpenedBuild);
|
||||
$('#openedBuild_chosen').remove();
|
||||
$('#pickerDropMenu-pk_openedBuild').remove();
|
||||
$('#openedBuild').next('.picker').remove();
|
||||
$("#openedBuild").chosen();
|
||||
notice();
|
||||
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch);
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').val(oldOpenedBuild).chosen()});
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
|
||||
var oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
|
||||
var link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').val(oldResolvedBuild).chosen()});
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').val(oldResolvedBuild).picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -595,28 +664,30 @@ function loadExecutionBuilds(executionID, num)
|
||||
if(typeof(branch) == 'undefined') var branch = 0;
|
||||
if(typeof(productID) == 'undefined') var productID = 0;
|
||||
|
||||
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
|
||||
|
||||
if(page == 'create')
|
||||
{
|
||||
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + "&branch=" + branch + "&index=0&needCreate=true");
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control" multiple=multiple></select>';
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control picker-select" multiple=multiple></select>';
|
||||
$('#openedBuild').replaceWith(data);
|
||||
$('#openedBuild').val(oldOpenedBuild);
|
||||
$('#openedBuild_chosen').remove();
|
||||
$('#pickerDropMenu-pk_openedBuild').remove();
|
||||
$('#openedBuild').next('.picker').remove();
|
||||
$("#openedBuild").chosen();
|
||||
notice();
|
||||
$("#openedBuild").picker({optionRender: markReleasedBuilds, dropWidth: 'auto'});
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&needCreate=false&type=normal&number=' + num);
|
||||
$('#openedBuildBox' + num).load(link, function(){$(this).find('select').val(oldOpenedBuild).chosen()});
|
||||
$('#openedBuildBox' + num).load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleaseBuilds, dropWidth: 'auto'})});
|
||||
|
||||
oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
|
||||
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').val(oldResolvedBuild).chosen()});
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').val(oldResolvedBuild).picker({optionRender: markReleasedBuilds, dropWidth: 'auto'})});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,7 +847,9 @@ function notice()
|
||||
if(page == 'edit') return;
|
||||
|
||||
$('#buildBoxActions').empty().hide();
|
||||
if($('#openedBuild').find('option').length <= 1)
|
||||
var itemCount = $('#openedBuild').find('option').length;
|
||||
if($('#openedBuild').attr('data-items') != undefined) var itemCount = $('#openedBuild').attr('data-items');
|
||||
if(itemCount <= 1)
|
||||
{
|
||||
var html = '';
|
||||
if($('#execution').length == 0 || $('#execution').val() == 0)
|
||||
|
||||
@@ -124,6 +124,7 @@ $(function()
|
||||
});
|
||||
});
|
||||
|
||||
$(window).unload(function(){
|
||||
$(window).unload(function()
|
||||
{
|
||||
if(blockID) window.parent.refreshBlock($('#block' + blockID));
|
||||
});
|
||||
|
||||
@@ -81,8 +81,6 @@ class bugModel extends model
|
||||
->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane,ticket')
|
||||
->get();
|
||||
|
||||
if($bug->execution != 0) $bug->project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($bug->execution)->fetch('project');
|
||||
|
||||
/* Check repeat bug. */
|
||||
$result = $this->loadModel('common')->removeDuplicate('bug', $bug, "product={$bug->product}");
|
||||
if($result and $result['stop']) return array('status' => 'exists', 'id' => $result['duplicate']);
|
||||
@@ -219,8 +217,6 @@ class bugModel extends model
|
||||
|
||||
if(isset($data->lanes[$i])) $bug->laneID = $data->lanes[$i];
|
||||
|
||||
if($bug->execution != 0) $bug->project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($bug->execution)->fetch('project');
|
||||
|
||||
/* Assign the bug to the person in charge of the module. */
|
||||
if(!empty($moduleOwners[$bug->module]))
|
||||
{
|
||||
@@ -1623,7 +1619,7 @@ class bugModel extends model
|
||||
$this->config->bug->search['params']['module']['values'] = $modules;
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($productID, 0, 'id_desc', $projectID);
|
||||
$this->config->bug->search['params']['severity']['values'] = array(0 => '') + $this->lang->bug->severityList; //Fix bug #939.
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, 'all', 'withbranch');
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, 'all', 'withbranch|releasetag');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
if($this->session->currentProductType == 'normal')
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<?php $this->printExtendFields($bug, 'table');?>
|
||||
<tr>
|
||||
<th><?php echo $lang->bug->openedBuild;?></th>
|
||||
<td colspan='2'><?php echo html::select('openedBuild[]', $builds, $bug->openedBuild, 'size=4 multiple=multiple class="form-control chosen"');?></td>
|
||||
<td colspan='2'><?php echo html::select('openedBuild[]', $builds, $bug->openedBuild, 'size=4 multiple=multiple class="form-control picker-select"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
@@ -56,4 +56,8 @@
|
||||
<div class='main'><?php include '../../common/view/action.html.php';?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
js::set('productID', $bug->product);
|
||||
js::set('releasedBuild', $lang->build->releasedBuild);
|
||||
?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<?php
|
||||
include '../../common/view/header.html.php';
|
||||
js::set('requiredFields', $config->bug->create->requiredFields);
|
||||
js::set('productID', $productID);
|
||||
js::set('releasedBuild', $lang->build->releasedBuild);
|
||||
?>
|
||||
<?php
|
||||
$visibleFields = array();
|
||||
@@ -107,7 +109,7 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange='loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
|
||||
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, 'trunk', "class='form-control chosen' multiple");?></td>
|
||||
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, 'trunk', "class='form-control picker-select' multiple");?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
@@ -163,7 +165,7 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
|
||||
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control chosen' multiple");?></td>
|
||||
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control picker-select' multiple");?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
@@ -224,7 +226,7 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
<td><?php echo html::select("modules[%s]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[%s]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, \"%s\")'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[%s]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, \"%s\")'");?></td>
|
||||
<td id='buildBox%s'><?php echo html::select("openedBuilds[%s][]", $builds, '', "class='form-control chosen' multiple");?></td>
|
||||
<td id='buildBox%s'><?php echo html::select("openedBuilds[%s][]", $builds, '', "class='form-control picker-select' multiple");?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
@@ -267,7 +269,7 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field)
|
||||
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
|
||||
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
|
||||
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control chosen' multiple");?></td>
|
||||
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control picker-select' multiple");?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
|
||||
@@ -328,7 +328,7 @@ $currentBrowseType = isset($lang->bug->mySelects[$browseType]) && in_array($brow
|
||||
{
|
||||
$actionLink = $this->createLink('bug', 'batchResolve', "resolution=fixed&resolvedBuild=$key");
|
||||
echo "<li class='option' data-key='$key'>";
|
||||
echo html::a('javascript:;', $build, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin', '#bugList')\"");
|
||||
echo html::a('javascript:;', (in_array($key, $releasedBuilds) ? "<span class='label label-primary label-outline'>{$lang->build->releasedBuild}</span> " : '') . $build, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin', '#bugList')\"");
|
||||
echo "</li>";
|
||||
}
|
||||
echo "</ul>";
|
||||
|
||||
@@ -30,6 +30,8 @@ js::set('tab', $this->app->tab);
|
||||
js::set('requiredFields', $config->bug->create->requiredFields);
|
||||
js::set('showFields', $showFields);
|
||||
js::set('projectExecutionPairs', $projectExecutionPairs);
|
||||
js::set('productID', $productID);
|
||||
js::set('releasedBuild', $lang->build->releasedBuild);
|
||||
if($this->app->tab == 'execution') js::set('objectID', zget($execution, 'id', ''));
|
||||
if($this->app->tab == 'project') js::set('objectID', $projectID);
|
||||
?>
|
||||
@@ -128,7 +130,7 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
|
||||
<td>
|
||||
<div class='input-group' id='buildBox'>
|
||||
<span class="input-group-addon"><?php echo $lang->bug->openedBuild?></span>
|
||||
<?php echo html::select('openedBuild[]', $builds, empty($buildID) ? '' : $buildID, "multiple=multiple class='chosen form-control'");?>
|
||||
<?php echo html::select('openedBuild[]', $builds, empty($buildID) ? '' : $buildID, "multiple=multiple class='picker-select form-control' data-items='" . count($builds) . "'");?>
|
||||
<span class='input-group-addon fix-border' id='buildBoxActions'></span>
|
||||
<div class='input-group-btn'><?php echo html::commonButton($lang->bug->allBuilds, "class='btn' id='all' data-toggle='tooltip' onclick='loadAllBuilds()'")?></div>
|
||||
</div>
|
||||
|
||||
@@ -30,6 +30,8 @@ js::set('bugID' , $bug->id);
|
||||
js::set('bugBranch' , $bug->branch);
|
||||
js::set('isClosedBug' , $bug->status == 'closed');
|
||||
js::set('projectExecutionPairs' , $projectExecutionPairs);
|
||||
js::set('productID' , $product->id);
|
||||
js::set('releasedBuild' , $lang->build->releasedBuild);
|
||||
if($this->app->tab == 'execution') js::set('objectID', $bug->execution);
|
||||
if($this->app->tab == 'project') js::set('objectID', $bug->project);
|
||||
?>
|
||||
@@ -100,7 +102,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
|
||||
<th class='w-80px'><?php echo $lang->bug->product;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('product', $products, $productID, "onchange='loadAll(this.value)' class='form-control chosen'");?>
|
||||
<?php echo html::select('product', $products, $product->id, "onchange='loadAll(this.value)' class='form-control chosen'");?>
|
||||
<?php if($product->type != 'normal') echo html::select('branch', $branchTagOption, $bug->branch, "onchange='loadBranch();' class='form-control'");?>
|
||||
</div>
|
||||
</td>
|
||||
@@ -114,9 +116,9 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
|
||||
if(count($moduleOptionMenu) == 1)
|
||||
{
|
||||
echo "<span class='input-group-addon'>";
|
||||
echo html::a($this->createLink('tree', 'browse', "rootID=$productID&view=bug¤tModuleID=0&branch=$bug->branch", '', true), $lang->tree->manage, '', "class='text-primary' data-toggle='modal' data-type='iframe' data-width='95%'");
|
||||
echo html::a($this->createLink('tree', 'browse', "rootID={$product->id}&view=bug¤tModuleID=0&branch=$bug->branch", '', true), $lang->tree->manage, '', "class='text-primary' data-toggle='modal' data-type='iframe' data-width='95%'");
|
||||
echo ' ';
|
||||
echo html::a("javascript:void(0)", $lang->refreshIcon, '', "class='refresh' title='$lang->refresh' onclick='loadProductModules($productID)'");
|
||||
echo html::a("javascript:void(0)", $lang->refreshIcon, '', "class='refresh' title='$lang->refresh' onclick='loadProductModules($product->id)'");
|
||||
echo '</span>';
|
||||
}
|
||||
?>
|
||||
@@ -240,7 +242,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
|
||||
<th><?php echo $lang->bug->openedBuild;?></th>
|
||||
<td>
|
||||
<div id='openedBuildBox' class='input-group'>
|
||||
<?php echo html::select('openedBuild[]', $openedBuilds, $bug->openedBuild, 'size=4 multiple=multiple class="chosen form-control"');?>
|
||||
<?php echo html::select('openedBuild[]', $openedBuilds, $bug->openedBuild, 'size=4 multiple=multiple class="picker-select form-control"');?>
|
||||
<span class='input-group-btn'><?php echo html::commonButton($lang->bug->allBuilds, "class='btn' onclick='loadAllBuilds(this)'")?></span>
|
||||
</div>
|
||||
</td>
|
||||
@@ -257,7 +259,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
|
||||
<th><?php echo $lang->bug->resolvedBuild;?></th>
|
||||
<td>
|
||||
<div id='resolvedBuildBox' class='input-group'>
|
||||
<?php echo html::select('resolvedBuild', $resolvedBuilds, $bug->resolvedBuild, "class='form-control chosen'");?>
|
||||
<?php echo html::select('resolvedBuild', $resolvedBuilds, $bug->resolvedBuild, "class='form-control picker-select'");?>
|
||||
<span class='input-group-btn'><?php echo html::commonButton($lang->bug->allBuilds, "class='btn' onclick='loadAllBuilds(this)'")?></span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php include '../../common/view/datepicker.html.php';?>
|
||||
<?php
|
||||
js::set('page' , 'resolve');
|
||||
js::set('productID' , $bug->product);
|
||||
js::set('page', 'resolve');
|
||||
js::set('productID', $bug->product);
|
||||
js::set('releasedBuild', $lang->build->releasedBuild);
|
||||
?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
@@ -49,7 +50,7 @@ js::set('productID' , $bug->product);
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div id='resolvedBuildBox'><?php echo html::select('resolvedBuild', $builds, '', "class='form-control chosen'");?></div>
|
||||
<div id='resolvedBuildBox'><?php echo html::select('resolvedBuild', $builds, '', "class='form-control picker-select'");?></div>
|
||||
<div id='newBuildBox' class='hidden required'><?php echo html::input('buildName', '', "class='form-control' placeholder='{$lang->bug->placeholder->newBuildName}'");?></div>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
+19
-13
@@ -385,32 +385,38 @@ class build extends control
|
||||
* @param string|int $branch
|
||||
* @param int $index the index of batch create bug.
|
||||
* @param string $type get all builds or some builds belong to normal releases and executions are not done.
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetProductBuilds($productID, $varName, $build = '', $branch = 'all', $index = 0, $type = 'normal')
|
||||
public function ajaxGetProductBuilds($productID, $varName, $build = '', $branch = 'all', $index = 0, $type = 'normal', $extra = '')
|
||||
{
|
||||
$isJsonView = $this->app->getViewType() == 'json';
|
||||
if($varName == 'openedBuild' )
|
||||
{
|
||||
$params = ($type == 'all') ? 'noempty,withbranch' : 'noempty,noterminate,nodone,withbranch';
|
||||
$params = ($type == 'all') ? 'noempty,withbranch,noreleased' : 'noempty,noterminate,nodone,withbranch,noreleased';
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $params, 0, 'project', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName . '[]', $builds, $build, 'size=4 class=form-control multiple'));
|
||||
}
|
||||
if($varName == 'openedBuilds' )
|
||||
{
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty', 0, 'project', $build);
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty,noreleased', 0, 'project', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName . "[$index][]", $builds, $build, 'size=4 class=form-control multiple'));
|
||||
}
|
||||
if($varName == 'resolvedBuild')
|
||||
{
|
||||
$params = ($type == 'all') ? 'withbranch' : 'noterminate,nodone,withbranch';
|
||||
$params = ($type == 'all') ? 'withbranch,noreleased' : 'noterminate,nodone,withbranch,noreleased';
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $params, 0, 'project', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName, $builds, $build, "class='form-control'"));
|
||||
}
|
||||
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $type, 0, 'project', $build);
|
||||
if(strpos($extra, 'multiple') !== false) $varName .= '[]';
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName, $builds, $build, "class='form-control chosen' $extra"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,7 +440,7 @@ class build extends control
|
||||
{
|
||||
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$params = ($type == 'all') ? 'noempty,withbranch' : 'noempty,noterminate,nodone,withbranch';
|
||||
$params = ($type == 'all') ? 'noempty,withbranch,noreleased' : 'noempty,noterminate,nodone,withbranch,noreleased';
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $params, $projectID, 'project', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName . '[]', $builds , '', 'size=4 class=form-control multiple'));
|
||||
@@ -443,13 +449,13 @@ class build extends control
|
||||
{
|
||||
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$params = ($type == 'all') ? 'withbranch' : 'noterminate,nodone,withbranch';
|
||||
$params = ($type == 'all') ? 'withbranch,noreleased' : 'noterminate,nodone,withbranch,noreleased';
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $params, $projectID, 'project', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName, $builds, $build, "class='form-control'"));
|
||||
}
|
||||
|
||||
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
if(empty($projectID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type, $extra);
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $type, $projectID, 'project', $build, false);
|
||||
if(strpos($extra, 'multiple') !== false) $varName .= '[]';
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
@@ -478,7 +484,7 @@ class build extends control
|
||||
{
|
||||
if(empty($executionID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$params = ($type == 'all') ? 'noempty' : 'noempty,noterminate,nodone';
|
||||
$params = ($type == 'all') ? 'noempty,noreleased' : 'noempty,noterminate,nodone,noreleased';
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $params, $executionID, 'execution', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
|
||||
@@ -489,7 +495,7 @@ class build extends control
|
||||
{
|
||||
if(empty($executionID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty', $executionID, 'execution', $build);
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty,noreleased', $executionID, 'execution', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName . "[$index][]", $builds , $build, 'size=4 class=form-control multiple'));
|
||||
}
|
||||
@@ -497,14 +503,14 @@ class build extends control
|
||||
{
|
||||
if(empty($executionID)) return $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$params = ($type == 'all') ? '' : 'noterminate,nodone';
|
||||
$params = ($type == 'all') ? ',noreleased' : 'noterminate,nodone,noreleased';
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, $params, $executionID, 'execution', $build);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
return print(html::select($varName, $builds, $build, "class='form-control'"));
|
||||
}
|
||||
if($varName == 'testTaskBuild')
|
||||
{
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty,notrunk', $executionID, 'execution');
|
||||
$builds = $this->build->getBuildPairs($productID, $branch, 'noempty,notrunk', $executionID, 'execution', '', false);
|
||||
if($isJsonView) return print(json_encode($builds));
|
||||
|
||||
if(empty($builds))
|
||||
@@ -543,7 +549,7 @@ class build extends control
|
||||
{
|
||||
$lastBuild = $this->build->getLast($executionID, $projectID);
|
||||
if($lastBuild)
|
||||
{
|
||||
{
|
||||
echo "<div class='help-block'> " . $this->lang->build->last . ": <a class='code label label-badge label-light' id='lastBuildBtn'>" . $lastBuild->name . "</a></div>";
|
||||
}
|
||||
else
|
||||
@@ -714,7 +720,7 @@ class build extends control
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($build->product, $build->branch, 'skipParent');
|
||||
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($build->product, 'bug', 0, $build->branch);
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($build->product, $build->branch, 'id_desc', $this->session->project);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->build->getBuildPairs($build->product, $branch = 'all', $params = '');
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->build->getBuildPairs($build->product, $branch = 'all', $params = 'releasetag');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
|
||||
unset($this->config->bug->search['fields']['product']);
|
||||
|
||||
@@ -36,6 +36,7 @@ $lang->build->execution = $lang->executionCommon;
|
||||
$lang->build->integrated = 'Integrated';
|
||||
$lang->build->singled = 'Singled';
|
||||
$lang->build->builds = 'Included Builds';
|
||||
$lang->build->releasedBuild = 'Released Build';
|
||||
$lang->build->name = 'Name';
|
||||
$lang->build->date = 'Datum';
|
||||
$lang->build->builder = 'Builder';
|
||||
@@ -60,6 +61,7 @@ $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the vers
|
||||
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
|
||||
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
|
||||
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
|
||||
$lang->build->notice->createTest = "The execution of this version has been deleted, and the test cannot be submitted";
|
||||
|
||||
$lang->build->finishStories = " %s {$lang->SRCommon} sind abgeschlossen.";
|
||||
$lang->build->resolvedBugs = ' %s Bugs sind gelöst.';
|
||||
|
||||
@@ -36,6 +36,7 @@ $lang->build->execution = $lang->executionCommon;
|
||||
$lang->build->integrated = 'Integrated';
|
||||
$lang->build->singled = 'Singled';
|
||||
$lang->build->builds = 'Included Builds';
|
||||
$lang->build->releasedBuild = 'Released Build';
|
||||
$lang->build->name = 'Name';
|
||||
$lang->build->date = 'Date';
|
||||
$lang->build->builder = 'Builder';
|
||||
@@ -60,6 +61,7 @@ $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the vers
|
||||
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
|
||||
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
|
||||
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
|
||||
$lang->build->notice->createTest = "The execution of this version has been deleted, and the test cannot be submitted";
|
||||
|
||||
$lang->build->finishStories = " Finished {$lang->SRCommon} %s";
|
||||
$lang->build->resolvedBugs = ' Resolved Bug %s';
|
||||
|
||||
@@ -36,6 +36,7 @@ $lang->build->execution = $lang->executionCommon;
|
||||
$lang->build->integrated = 'Integrated';
|
||||
$lang->build->singled = 'Singled';
|
||||
$lang->build->builds = 'Included Builds';
|
||||
$lang->build->releasedBuild = 'Released Build';
|
||||
$lang->build->name = 'Nom';
|
||||
$lang->build->date = 'Date';
|
||||
$lang->build->builder = 'Builder';
|
||||
@@ -60,6 +61,7 @@ $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the vers
|
||||
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
|
||||
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
|
||||
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
|
||||
$lang->build->notice->createTest = "The execution of this version has been deleted, and the test cannot be submitted";
|
||||
|
||||
$lang->build->finishStories = " {$lang->SRCommon} Terminées %s";
|
||||
$lang->build->resolvedBugs = ' Bugs Résolus %s';
|
||||
|
||||
@@ -54,6 +54,7 @@ $lang->build->notice->changeProduct = "The {$lang->SRCommon}, bug, or the vers
|
||||
$lang->build->notice->changeExecution = "The version of the submitted test order cannot be modified {$lang->executionCommon}";
|
||||
$lang->build->notice->changeBuilds = "The version of the submitted test order cannot be modified builds";
|
||||
$lang->build->notice->autoRelation = "The completed requirements, resolved bugs, and generated bugs under the relevant version will be automatically associated with the project version";
|
||||
$lang->build->notice->createTest = "The execution of this version has been deleted, and the test cannot be submitted";
|
||||
|
||||
$lang->build->finishStories = " {$lang->SRCommon} đã kết thúc %s";
|
||||
$lang->build->resolvedBugs = ' Bug đã giải quyết %s';
|
||||
|
||||
@@ -28,7 +28,7 @@ $lang->build->confirmUnlinkBug = "您确认移除该Bug吗?";
|
||||
$lang->build->basicInfo = '基本信息';
|
||||
|
||||
$lang->build->id = 'ID';
|
||||
$lang->build->product = $lang->productCommon;
|
||||
$lang->build->product = '所属' . $lang->productCommon;
|
||||
$lang->build->project = '所属项目';
|
||||
$lang->build->branch = '平台/分支';
|
||||
$lang->build->branchName = '所属%s';
|
||||
@@ -36,6 +36,7 @@ $lang->build->execution = '所属' . $lang->executionCommon;
|
||||
$lang->build->integrated = '集成版本';
|
||||
$lang->build->singled = '单一版本';
|
||||
$lang->build->builds = '包含版本';
|
||||
$lang->build->releasedBuild = '发布版本';
|
||||
$lang->build->name = '名称编号';
|
||||
$lang->build->date = '打包日期';
|
||||
$lang->build->builder = '构建者';
|
||||
@@ -60,6 +61,7 @@ $lang->build->notice->changeProduct = "已经关联{$lang->SRCommon}、Bug或
|
||||
$lang->build->notice->changeExecution = "提交测试单的版本,不能修改其所属{$lang->executionCommon}";
|
||||
$lang->build->notice->changeBuilds = "提交测试单的版本,不能修改关联版本";
|
||||
$lang->build->notice->autoRelation = "相关版本下完成的需求、解决的Bug、产生的Bug将会自动关联到项目版本中";
|
||||
$lang->build->notice->createTest = "该版本所属执行已删除,不能提交测试";
|
||||
|
||||
$lang->build->finishStories = " 本次共完成 %s 个{$lang->SRCommon}";
|
||||
$lang->build->resolvedBugs = ' 本次共解决 %s 个Bug';
|
||||
|
||||
+45
-4
@@ -181,6 +181,38 @@ class buildModel extends model
|
||||
return $this->getExecutionBuilds($executionID, 'bysearch', $buildQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter linked stories or bugs builds.
|
||||
*
|
||||
* @param array $buildIdList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function filterLinked($buildIdList)
|
||||
{
|
||||
$linkeds = array();
|
||||
$buildList = $this->getByList($buildIdList);
|
||||
foreach($buildList as $build)
|
||||
{
|
||||
if(!$build->execution && !empty($build->builds))
|
||||
{
|
||||
$childBuilds = $this->getByList($build->builds);
|
||||
foreach($childBuilds as $childBuild)
|
||||
{
|
||||
$childBuild->stories = trim($childBuild->stories, ',');
|
||||
$childBuild->bugs = trim($childBuild->bugs, ',');
|
||||
|
||||
if($childBuild->stories) $build->stories .= ',' . $childBuild->stories;
|
||||
if($childBuild->bugs) $build->bugs .= ',' . $childBuild->bugs;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($build->stories) or !empty($build->bugs)) $linkeds[$build->id] = $build->id;
|
||||
}
|
||||
|
||||
return $linkeds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get story builds.
|
||||
*
|
||||
@@ -202,7 +234,7 @@ class buildModel extends model
|
||||
*
|
||||
* @param int|array $products
|
||||
* @param string|int $branch
|
||||
* @param string $params noempty|notrunk|noterminate|withbranch|hasproject|noDeleted|singled|withreleased, can be a set of them
|
||||
* @param string $params noempty|notrunk|noterminate|withbranch|hasproject|noDeleted|singled|noreleased|releasedtag, can be a set of them
|
||||
* @param string|int $objectID
|
||||
* @param string $objectType
|
||||
* @param int|array $buildIdList
|
||||
@@ -227,7 +259,7 @@ class buildModel extends model
|
||||
}
|
||||
|
||||
$branchs = strpos($params, 'separate') === false ? "0,$branch" : $branch;
|
||||
$allBuilds = $this->dao->select('t1.id, t1.name, t1.date, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t4.name as branchName, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
|
||||
$allBuilds = $this->dao->select('t1.id, t1.name, t1.execution, t1.date, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t4.name as branchName, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
|
||||
->beginIF($objectType === 'execution')->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')->fi()
|
||||
->beginIF($objectType === 'project')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')->fi()
|
||||
->leftJoin(TABLE_RELEASE)->alias('t3')->on("FIND_IN_SET(t1.id,t3.build)")
|
||||
@@ -243,6 +275,8 @@ class buildModel extends model
|
||||
->beginIF($branch !== 'all')->andWhere('t1.branch')->in("$branchs")->fi()
|
||||
->orderBy('t1.date desc, t1.id desc')->fetchAll('id');
|
||||
|
||||
$deletedExecutions = $this->dao->select('id, deleted')->from(TABLE_EXECUTION)->where('type')->eq('sprint')->andWhere('deleted')->eq('1')->fetchPairs();
|
||||
|
||||
/* Set builds and filter done executions and terminate releases. */
|
||||
$builds = array();
|
||||
$buildIdList = array();
|
||||
@@ -251,6 +285,7 @@ class buildModel extends model
|
||||
{
|
||||
if(empty($build->releaseID) and (strpos($params, 'nodone') !== false) and ($build->objectStatus === 'done')) continue;
|
||||
if((strpos($params, 'noterminate') !== false) and ($build->releaseStatus === 'terminate')) continue;
|
||||
if((strpos($params, 'withexecution') !== false) and $build->execution and isset($executions[$build->execution])) continue;
|
||||
|
||||
if($build->deleted == 1) $build->name .= ' (' . $this->lang->build->deleted . ')';
|
||||
$branchName = $build->branchName ? $build->branchName : $this->lang->branch->main;
|
||||
@@ -292,12 +327,13 @@ class buildModel extends model
|
||||
$releaseName = $release->name;
|
||||
$branchName = $release->branchName ? $release->branchName : $this->lang->branch->main;
|
||||
if($release->productType != 'normal') $releaseName = (strpos($params, 'withbranch') !== false ? $branchName . '/' : '') . $releaseName;
|
||||
if(strpos($params, 'releasetag') !== false) $releaseName = "[{$this->lang->build->releasedBuild}] " . $releaseName;
|
||||
$builds[$release->date][$release->shadow] = $releaseName;
|
||||
foreach(explode(',', trim($release->build, ',')) as $buildID)
|
||||
{
|
||||
if(!isset($allBuilds[$buildID])) continue;
|
||||
$build = $allBuilds[$buildID];
|
||||
if(strpos($params, 'withreleased') === false) unset($builds[$build->date][$buildID]);
|
||||
if(strpos($params, 'noreleased') !== false) unset($builds[$build->date][$buildID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,6 +657,8 @@ class buildModel extends model
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if($module == 'testtask' and $action == 'create') return !$object->executionDeleted;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -649,11 +687,14 @@ class buildModel extends model
|
||||
{
|
||||
$executionID = $tab == 'execution' ? $extraParams['executionID'] : $build->execution;
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
$build->executionDeleted = $execution ? $execution->deleted : 0;
|
||||
|
||||
$testtaskApp = (!empty($execution->type) and $execution->type == 'kanban') ? 'data-app="qa"' : "data-app='{$tab}'";
|
||||
|
||||
if(common::hasPriv($module, 'linkstory') and common::canBeChanged('build', $build)) $menu .= $this->buildMenu($module, 'view', "{$params}&type=story&link=true", $build, $type, 'link', '', '', '', "data-app={$tab}", $this->lang->build->linkStory);
|
||||
|
||||
$menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id&projectID=$build->project", $build, $type, 'bullhorn', '', '', '', $testtaskApp);
|
||||
$title = ($execution and $execution->deleted === '1') ? $this->lang->build->notice->createTest : '';
|
||||
$menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id&projectID=$build->project", $build, $type, 'bullhorn', '', '', '', $testtaskApp, $title);
|
||||
|
||||
if($tab == 'execution' and !empty($execution->type) and $execution->type != 'kanban') $menu .= $this->buildMenu('execution', 'bug', "execution={$extraParams['executionID']}&productID={$extraParams['productID']}&branchID=all&orderBy=status&build=$build->id", $build, $type, '', '', '', '', $this->lang->execution->viewBug);
|
||||
if($tab == 'project' or empty($execution->type) or $execution->type == 'kanban') $menu .= $this->buildMenu($module, 'view', "{$params}&type=generatedBug", $build, $type, 'bug', '', '', '', "data-app='$tab'", $this->lang->project->bug);
|
||||
|
||||
@@ -26,7 +26,11 @@ tbody tr td:first-child input {display: none;}
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php $browseLink = $this->session->buildList ? $this->session->buildList : $this->createLink('execution', 'build', "executionID=$build->execution");?>
|
||||
<?php common::printBack($browseLink, 'btn btn-secondary');?>
|
||||
<?php
|
||||
$dataApp = strpos($browseLink, 'release') !== false ? 'data-app=product' : '';
|
||||
if(strpos($browseLink, 'projectrelease') !== false) $dataApp = 'data-app=project';
|
||||
?>
|
||||
<?php common::printBack($browseLink, 'btn btn-secondary', $dataApp);?>
|
||||
<div class='divider'></div>
|
||||
<div class='page-title'>
|
||||
<span title='<?php echo $build->name;?>'>
|
||||
|
||||
@@ -2365,6 +2365,8 @@ EOD;
|
||||
*/
|
||||
public function checkSafeFile()
|
||||
{
|
||||
if($this->app->isContainer()) return false;
|
||||
|
||||
if($this->app->getModuleName() == 'upgrade' and $this->session->upgrading) return false;
|
||||
|
||||
$statusFile = $this->app->getAppRoot() . 'www' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'ok.txt';
|
||||
|
||||
@@ -249,6 +249,7 @@ $lang->doc->errorEmptyLib = 'No data in document library.';
|
||||
$lang->doc->confirmUpdateContent = 'You have a document that is not saved from last time. Do you want to continue editing it?';
|
||||
$lang->doc->selectLibType = 'Please select a type of doc library.';
|
||||
$lang->doc->noLibreOffice = 'You does not have access to office conversion settings!';
|
||||
$lang->doc->errorParentChapter = 'The parent chapter cannot be its own chapter or sub chapter!';
|
||||
|
||||
$lang->doc->noticeAcl['lib']['product']['default'] = 'Users who can access the selected product can access it.';
|
||||
$lang->doc->noticeAcl['lib']['product']['custom'] = 'Users who can access the selected product or users in the whiltelist can access it.';
|
||||
|
||||
@@ -249,6 +249,7 @@ $lang->doc->errorEmptyLib = 'No data in document library.';
|
||||
$lang->doc->confirmUpdateContent = 'You have a document that is not saved from last time. Do you want to continue editing it?';
|
||||
$lang->doc->selectLibType = 'Please select a type of doc library.';
|
||||
$lang->doc->noLibreOffice = 'You does not have access to office conversion settings!';
|
||||
$lang->doc->errorParentChapter = 'The parent chapter cannot be its own chapter or sub chapter!';
|
||||
|
||||
$lang->doc->noticeAcl['lib']['product']['default'] = 'Users who can access the selected product can access it.';
|
||||
$lang->doc->noticeAcl['lib']['product']['custom'] = 'Users who can access the selected product or users in the whiltelist can access it.';
|
||||
|
||||
@@ -249,6 +249,7 @@ $lang->doc->errorEmptyLib = 'No data in document library.';
|
||||
$lang->doc->confirmUpdateContent = 'You have a document that is not saved from last time. Do you want to continue editing it?';
|
||||
$lang->doc->selectLibType = 'Please select a type of doc library.';
|
||||
$lang->doc->noLibreOffice = 'You does not have access to office conversion settings!';
|
||||
$lang->doc->errorParentChapter = 'The parent chapter cannot be its own chapter or sub chapter!';
|
||||
|
||||
$lang->doc->noticeAcl['lib']['product']['default'] = 'Les utilisateurs qui ont accès au Product peuvent y accéder.';
|
||||
$lang->doc->noticeAcl['lib']['product']['custom'] = 'Les utilisateurs qui ont accès au Product ou les utilisateurs de la Liste Blanche peuvent y accéder.';
|
||||
|
||||
@@ -249,6 +249,7 @@ $lang->doc->errorEmptyLib = '文档库暂无数据。';
|
||||
$lang->doc->confirmUpdateContent = '检查到您有未保存的文档内容,是否继续编辑?';
|
||||
$lang->doc->selectLibType = '请选择文档库类型';
|
||||
$lang->doc->noLibreOffice = '您还没有office转换设置访问权限!';
|
||||
$lang->doc->errorParentChapter = '父章节不能是自身章节及子章节!';
|
||||
|
||||
$lang->doc->noticeAcl['lib']['product']['default'] = '有所选产品访问权限的用户可以访问。';
|
||||
$lang->doc->noticeAcl['lib']['product']['custom'] = '有所选产品访问权限或白名单里的用户可以访问。';
|
||||
|
||||
@@ -821,6 +821,16 @@ class docModel extends model
|
||||
->remove('comment,files,labels,uid,contactListMenu')
|
||||
->get();
|
||||
|
||||
if($doc->type == 'chapter' and $doc->parent)
|
||||
{
|
||||
$parentDoc = $this->dao->select('*')->from(TABLE_DOC)->where('id')->eq((int)$doc->parent)->fetch();
|
||||
if(strpos($parentDoc->path, ",$docID,") !== false)
|
||||
{
|
||||
dao::$errors['parent'] = $this->lang->doc->errorParentChapter;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($doc->acl) and $doc->acl == 'private') $doc->users = $oldDoc->addedBy;
|
||||
|
||||
$oldDocContent = $this->dao->select('*')->from(TABLE_DOCCONTENT)->where('doc')->eq($docID)->andWhere('version')->eq($oldDoc->version)->fetch();
|
||||
|
||||
@@ -1097,7 +1097,7 @@ class execution extends control
|
||||
$modules = $this->tree->getAllModulePairs('bug');
|
||||
|
||||
/* Get module tree.*/
|
||||
$extra = array('executionID' => $executionID, 'orderBy' => $orderBy, 'type' => $type, 'build' => $build, 'branchID' => $branch);
|
||||
$extra = array('projectID' => $executionID, 'orderBy' => $orderBy, 'type' => $type, 'build' => $build, 'branchID' => $branch);
|
||||
if($executionID and empty($productID) and count($products) > 1)
|
||||
{
|
||||
$moduleTree = $this->tree->getBugTreeMenu($executionID, $productID, 0, array('treeModel', 'createBugLink'), $extra);
|
||||
@@ -1205,7 +1205,7 @@ class execution extends control
|
||||
}
|
||||
else
|
||||
{
|
||||
$moduleTree = $this->tree->getTreeMenu($productID, 'case', 0, array('treeModel', 'createCaseLink'), array('executionID' => $executionID, 'productID' => $productID), $branchID);
|
||||
$moduleTree = $this->tree->getTreeMenu($productID, 'case', 0, array('treeModel', 'createCaseLink'), array('projectID' => $executionID, 'productID' => $productID), $branchID);
|
||||
}
|
||||
$tree = $moduleID ? $this->tree->getByID($moduleID) : '';
|
||||
|
||||
|
||||
@@ -67,7 +67,8 @@ function renderUserAvatar(user, objectType, objectID, size, objectStatus)
|
||||
if(objectType == 'bug' && !priv.canAssignBug) return $noPrivAvatar;
|
||||
|
||||
var realname = user.realname ? user.realname : user.account;
|
||||
return objectStatus == 'closed' ? '' : $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + realname + '" href="' + link + '"/>').avatar({user: user});
|
||||
var title = user.title ? user.title : realname;
|
||||
return objectStatus == 'closed' ? '' : $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + title + '" href="' + link + '"/>').avatar({user: user});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,8 +287,9 @@ function renderTaskItem(item, $item, col)
|
||||
{
|
||||
var priHtml = '<span class="info info-pri' + (item.pri ? ' label-pri label-pri-' + item.pri : '') + '" title="' + item.pri + '">' + item.pri + '</span>';
|
||||
var hoursHtml = scaleSize <= 1 && item.status != 'wait' ? ('<span class="info info-estimate text-muted">' + taskLang.leftAB + ' ' + item.left + 'h</span>') : ('<span class="info info-estimate text-muted">' + taskLang.estimateAB + ' ' + item.estimate + 'h</span>');
|
||||
var avatarHtml = renderUserAvatar(item.assignedTo, 'task', item.id, '', col.type);
|
||||
|
||||
var avatarHtml = '';
|
||||
if(item.assignedTo == '' && item.mode == 'multi') avatarHtml = renderUserAvatar({title: item.teamMembers, realname: teamWords}, 'task', item.id, '', col.type);
|
||||
else avatarHtml = renderUserAvatar(item.assignedTo, 'task', item.id, '', col.type);
|
||||
var $infos = $item.find('.infos');
|
||||
if(!$infos.length) $infos = $('<div class="infos"></div>');
|
||||
$infos.html([priHtml, hoursHtml].join(''));
|
||||
|
||||
@@ -345,7 +345,7 @@ $lang->execution->timeSummary = '<div class="table-col"><div class="cle
|
||||
$lang->execution->groupSummaryAB = "<div>Aufgaben <strong>%s</strong></div><div><span class='text-muted'>Wartend</span> %s <span class='text-muted'>In Arbeit</span> %s</div><div>Geplant <strong>%s</strong></div><div><span class='text-muted'>Genutzt</span> %s <span class='text-muted'>Rest</span> %s</div>";
|
||||
$lang->execution->wbs = "Aufgaben aufteilen";
|
||||
$lang->execution->batchWBS = "Mehrere aufteilen";
|
||||
$lang->execution->howToUpdateBurn = "<a href='http://api.zentao.net/goto.php?item=burndown&lang=zh-cn' target='_blank' title='Wie wird der Burndown Chart aktualisiert?' class='btn btn-link'>Hilfe <i class='icon icon-help'></i></a>";
|
||||
$lang->execution->howToUpdateBurn = "<a href='https://api.zentao.pm/goto.php?item=burndown' target='_blank' title='Wie wird der Burndown Chart aktualisiert?' class='btn btn-link'>Hilfe <i class='icon icon-help'></i></a>";
|
||||
$lang->execution->whyNoStories = "Keine Story kann verknüpft werden. Bitte prüfen Sie ob ein Story mit {$lang->executionCommon} verknüpft ist {$lang->productCommon} und stellen Sie sicher das diese geprüft ist.";
|
||||
$lang->execution->projectNoStories = "No story can be linked. Please check whether there is any story in project and make sure it has been reviewed.";
|
||||
$lang->execution->productStories = "{$lang->executionCommon} verknüpfte Story ist ein Subset von {$lang->productCommon}, welche nur nach überprüfung verknüpft werden kann. Bitte <a href='%s'> Story verknüpfen</a>。";
|
||||
@@ -478,6 +478,8 @@ $lang->execution->kanbanViewList['story'] = "{$lang->SRCommon}";
|
||||
$lang->execution->kanbanViewList['bug'] = 'Bug';
|
||||
$lang->execution->kanbanViewList['task'] = 'Task';
|
||||
|
||||
$lang->execution->teamWords = 'Team';
|
||||
|
||||
$lang->kanbanSetting = new stdclass();
|
||||
$lang->kanbanSetting->noticeReset = 'Möchten Sie die Einstellungen des Kanbans zurücksetzen?';
|
||||
$lang->kanbanSetting->optionList['0'] = 'Verstecken';
|
||||
|
||||
@@ -478,6 +478,8 @@ $lang->execution->kanbanViewList['story'] = "{$lang->SRCommon}";
|
||||
$lang->execution->kanbanViewList['bug'] = 'Bug';
|
||||
$lang->execution->kanbanViewList['task'] = 'Task';
|
||||
|
||||
$lang->execution->teamWords = 'Team';
|
||||
|
||||
$lang->kanbanSetting = new stdclass();
|
||||
$lang->kanbanSetting->noticeReset = 'Do you want to reset Kanban?';
|
||||
$lang->kanbanSetting->optionList['0'] = 'Hide';
|
||||
|
||||
@@ -478,6 +478,8 @@ $lang->execution->kanbanViewList['story'] = "{$lang->SRCommon}";
|
||||
$lang->execution->kanbanViewList['bug'] = 'Bug';
|
||||
$lang->execution->kanbanViewList['task'] = 'Task';
|
||||
|
||||
$lang->execution->teamWords = 'Team';
|
||||
|
||||
$lang->kanbanSetting = new stdclass();
|
||||
$lang->kanbanSetting->noticeReset = 'Voulez-vous réinitialiser le tableau Kanban ?';
|
||||
$lang->kanbanSetting->optionList['0'] = 'Masquer';
|
||||
|
||||
@@ -436,4 +436,6 @@ $lang->execution->statusColorList['doing'] = '#0BD986';
|
||||
$lang->execution->statusColorList['suspended'] = '#fdc137';
|
||||
$lang->execution->statusColorList['closed'] = '#838A9D';
|
||||
|
||||
$lang->execution->teamWords = 'đội';
|
||||
|
||||
$lang->execution->boardColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#7FBB00', '#424BAC', '#66c5f8', '#EC2761');
|
||||
|
||||
@@ -478,6 +478,8 @@ $lang->execution->kanbanViewList['story'] = "{$lang->SRCommon}看板";
|
||||
$lang->execution->kanbanViewList['bug'] = 'Bug看板';
|
||||
$lang->execution->kanbanViewList['task'] = '任务看板';
|
||||
|
||||
$lang->execution->teamWords = '团队';
|
||||
|
||||
$lang->kanbanSetting = new stdclass();
|
||||
$lang->kanbanSetting->noticeReset = '是否恢复看板默认设置?';
|
||||
$lang->kanbanSetting->optionList['0'] = '隐藏';
|
||||
|
||||
@@ -453,4 +453,6 @@ $lang->execution->statusColorList['doing'] = '#0BD986';
|
||||
$lang->execution->statusColorList['suspended'] = '#fdc137';
|
||||
$lang->execution->statusColorList['closed'] = '#838A9D';
|
||||
|
||||
$lang->execution->teamWords = '團隊';
|
||||
|
||||
$lang->execution->boardColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#7FBB00', '#424BAC', '#66c5f8', '#EC2761');
|
||||
|
||||
@@ -161,7 +161,8 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if(isset($project->model) and $project->model == 'scrum') $hidden = '';?>
|
||||
<?php $hidden = 'hide'?>
|
||||
<?php if(isset($project->model) and !empty($project->hasProduct) and $project->model == 'scrum') $hidden = '';?>
|
||||
<tr class="<?php echo $hidden?>">
|
||||
<th><?php echo $lang->execution->linkPlan;?></th>
|
||||
<td colspan="3" id="plansBox">
|
||||
|
||||
@@ -231,4 +231,5 @@ js::set('priv',
|
||||
<?php js::set('orderBy', $storyOrder);?>
|
||||
<?php js::set('defaultMinColWidth', $this->config->minColWidth);?>
|
||||
<?php js::set('defaultMaxColWidth', $this->config->maxColWidth);?>
|
||||
<?php js::set('teamWords', $lang->execution->teamWords);?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -780,11 +780,10 @@ class extensionModel extends model
|
||||
/**
|
||||
* Update an extension.
|
||||
*
|
||||
* @param string $extension
|
||||
* @param string $status
|
||||
* @param array $files
|
||||
* @param string $extension
|
||||
* @param array|object $data
|
||||
* @access public
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
public function updateExtension($extension, $data)
|
||||
{
|
||||
|
||||
+9
-23
@@ -221,34 +221,20 @@ class file extends control
|
||||
$this->view->fields = $this->post->fields;
|
||||
$this->view->rows = $this->post->rows;
|
||||
$this->host = common::getSysURL();
|
||||
$kind = $this->post->kind;
|
||||
|
||||
switch($this->post->kind)
|
||||
foreach($this->view->rows as $row)
|
||||
{
|
||||
case 'task':
|
||||
foreach($this->view->rows as $row)
|
||||
foreach($row as &$field)
|
||||
{
|
||||
$row->name = html::a($this->host . $this->createLink('task', 'view', "taskID=$row->id"), $row->name);
|
||||
if(empty($field)) continue;
|
||||
$field = preg_replace('/ src="{([0-9]+)(\.(\w+))?}" /', ' src="' . $this->host . helper::createLink('file', 'read', "fileID=$1", "$3") . '" ', $field);
|
||||
}
|
||||
break;
|
||||
case 'story':
|
||||
foreach($this->view->rows as $row)
|
||||
{
|
||||
$row->title= html::a($this->host . $this->createLink('story', 'view', "storyID=$row->id"), $row->title);
|
||||
}
|
||||
break;
|
||||
case 'bug':
|
||||
foreach($this->view->rows as $row)
|
||||
{
|
||||
$row->title= html::a($this->host . $this->createLink('bug', 'view', "bugID=$row->id"), $row->title);
|
||||
}
|
||||
break;
|
||||
case 'testcase':
|
||||
foreach($this->view->rows as $row)
|
||||
{
|
||||
$row->title= html::a($this->host . $this->createLink('testcase', 'view', "caseID=$row->id"), $row->title);
|
||||
}
|
||||
break;
|
||||
|
||||
if(in_array($kind, array('story', 'bug', 'testcase'))) $row->title = html::a($this->host . $this->createLink($kind, 'view', "{$kind}ID=$row->id"), $row->title);
|
||||
if($kind == 'task') $row->name = html::a($this->host . $this->createLink('task', 'view', "taskID=$row->id"), $row->name);
|
||||
}
|
||||
|
||||
$this->view->fileName = $this->post->fileName;
|
||||
$output = $this->parse('file', 'export2Html');
|
||||
|
||||
|
||||
@@ -667,7 +667,6 @@ class fileModel extends model
|
||||
public function pasteImage($data, $uid = '', $safe = false)
|
||||
{
|
||||
if(empty($data)) return '';
|
||||
$data = str_replace('\"', '"', $data);
|
||||
|
||||
$dataLength = strlen($data);
|
||||
if(ini_get('pcre.backtrack_limit') < $dataLength) ini_set('pcre.backtrack_limit', $dataLength);
|
||||
@@ -676,7 +675,8 @@ class fileModel extends model
|
||||
{
|
||||
foreach($out[3] as $key => $base64Image)
|
||||
{
|
||||
$extension = strtolower($out[2][$key]);
|
||||
$base64Image = str_replace('\"', '"', $base64Image);
|
||||
$extension = strtolower($out[2][$key]);
|
||||
if(!in_array($extension, $this->config->file->imageExtensions)) helper::end();
|
||||
$imageData = base64_decode($base64Image);
|
||||
|
||||
|
||||
@@ -266,7 +266,10 @@ class install extends control
|
||||
$this->setting->setItem('system.common.safe.changeWeak', '1');
|
||||
$this->setting->setItem('system.common.global.cron', 1);
|
||||
|
||||
if(strpos($this->app->getClientLang(), 'zh') === 0) $this->loadModel('api')->createDemoData($this->lang->api->zentaoAPI, 'http://' . $_SERVER['HTTP_HOST'] . $this->app->config->webRoot . 'api.php/v1', '16.0');
|
||||
$httpType = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http';
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') $httpType = 'https';
|
||||
if(isset($_SERVER['REQUEST_SCHEME']) and strtolower($_SERVER['REQUEST_SCHEME']) == 'https') $httpType = 'https';
|
||||
if(strpos($this->app->getClientLang(), 'zh') === 0) $this->loadModel('api')->createDemoData($this->lang->api->zentaoAPI, "{$httpType}://{$_SERVER['HTTP_HOST']}" . $this->app->config->webRoot . 'api.php/v1', '16.0');
|
||||
return print(js::locate(inlink('step6'), 'parent'));
|
||||
}
|
||||
|
||||
|
||||
@@ -1511,6 +1511,8 @@ class kanbanModel extends model
|
||||
$cardData['status'] = $object->status;
|
||||
$cardData['left'] = $object->left;
|
||||
$cardData['estStarted'] = $object->estStarted;
|
||||
$cardData['mode'] = $object->mode;
|
||||
if($object->mode == 'multi') $cardData['teamMembers'] = $object->teamMembers;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -114,7 +114,6 @@ class messageModel extends model
|
||||
$this->loadModel('webhook')->send($objectType, $objectID, $actionType, $actionID, $actor);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($messageSetting['message']))
|
||||
{
|
||||
$actions = $messageSetting['message']['setting'];
|
||||
@@ -201,6 +200,14 @@ class messageModel extends model
|
||||
|
||||
if(!empty($notifyPersons)) $toList = implode(',', $notifyPersons);
|
||||
}
|
||||
if(empty($toList) and $objectType == 'task' and $object->mode == 'multi')
|
||||
{
|
||||
$teamMembers = $this->loadModel('task')->getTeamMembers($object->id);
|
||||
$toList = array_filter($teamMembers, function($account){
|
||||
return $account != $this->app->user->account;
|
||||
});
|
||||
$toList = implode(',', $toList);
|
||||
}
|
||||
|
||||
if($toList == 'closed') $toList = '';
|
||||
if($objectType == 'feedback' and $object->status == 'replied') $toList = ',' . $object->openedBy . ',';
|
||||
|
||||
@@ -699,8 +699,8 @@ class mr extends control
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($productID => $productID));
|
||||
$this->config->bug->search['params']['module']['values'] = $modules;
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->product->getExecutionPairsByProduct($productID);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, $branch = 'all', $params = '');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, $branch = 'all', $params = '');
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, $branch = 'all', $params = 'releasetag');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
|
||||
unset($this->config->bug->search['fields']['product']);
|
||||
if($product->type == 'normal')
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
.tip {margin-top: 10px;}
|
||||
.table-form>tbody>tr>th {white-space: nowrap; !important}
|
||||
.table-form>tbody>tr>td {width: 75%; !important}
|
||||
|
||||
+2
-2
@@ -640,7 +640,7 @@ class myModel extends model
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs();
|
||||
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getAllModulePairs();
|
||||
$this->config->bug->search['params']['severity']['values'] = array(0 => '') + $this->lang->bug->severityList;
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($products);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($products, 'all', 'releasetag');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->bug->search);
|
||||
@@ -911,7 +911,7 @@ class myModel extends model
|
||||
$this->config->ticket->search['params']['module']['values'] = array('' => '') + $this->loadModel('tree')->getAllModulePairs();
|
||||
$grantProducts = $this->loadModel('feedback')->getGrantProducts();
|
||||
$productIDlist = array_keys($grantProducts);
|
||||
$this->config->ticket->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productIDlist);
|
||||
$this->config->ticket->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productIDlist, 'all', 'releasetag');
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->ticket->search);
|
||||
}
|
||||
|
||||
@@ -271,13 +271,30 @@ class product extends control
|
||||
/* Display status of branch. */
|
||||
$branchOption = array();
|
||||
$branchTagOption = array();
|
||||
if($product and $product->type != 'normal')
|
||||
if(!$product and $isProjectStory)
|
||||
{
|
||||
$branches = $this->loadModel('branch')->getList($productID, $projectID, 'all');
|
||||
foreach($branches as $branchInfo)
|
||||
/* Get branch display under multiple products. */
|
||||
foreach($projectProducts as $projectProduct)
|
||||
{
|
||||
$branchOption[$branchInfo->id] = $branchInfo->name;
|
||||
$branchTagOption[$branchInfo->id] = $branchInfo->name . ($branchInfo->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : '');
|
||||
if($projectProduct and $projectProduct->type != 'normal')
|
||||
{
|
||||
$branches = $this->loadModel('branch')->getList($projectProduct->id, $projectID, 'all');
|
||||
foreach($branches as $branchInfo) $branchOptions[$projectProduct->id][$branchInfo->id] = $branchInfo->name;
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->branchOptions = $branchOptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($product and $product->type != 'normal')
|
||||
{
|
||||
$branches = $this->loadModel('branch')->getList($productID, $projectID, 'all');
|
||||
foreach($branches as $branchInfo)
|
||||
{
|
||||
$branchOption[$branchInfo->id] = $branchInfo->name;
|
||||
$branchTagOption[$branchInfo->id] = $branchInfo->name . ($branchInfo->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1351,7 +1368,7 @@ class product extends control
|
||||
$this->view->title = $this->lang->product->line;
|
||||
$this->view->position[] = $this->lang->product->line;
|
||||
|
||||
$this->view->programs = array('') + $this->loadModel('program')->getTopPairs();
|
||||
$this->view->programs = array('') + $this->loadModel('program')->getTopPairs('', 'withDeleted');
|
||||
$this->view->lines = $this->product->getLines();
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -357,6 +357,7 @@ js::set('vision', $this->config->vision);
|
||||
<?php foreach($stories as $story):?>
|
||||
<tr data-id='<?php echo $story->id?>' data-estimate='<?php echo $story->estimate?>' <?php if(!empty($story->children)) echo "data-children=" . count($story->children);?> data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
|
||||
<?php $story->from = $from;?>
|
||||
<?php if(!empty($branchOptions) and isset($branchOptions[$story->product])) $branchOption = $branchOptions[$story->product];?>
|
||||
<?php if($this->app->getViewType() == 'xhtml'):?>
|
||||
<?php
|
||||
foreach($setting as $key => $value)
|
||||
|
||||
@@ -809,8 +809,8 @@ class productplan extends control
|
||||
$this->config->bug->search['style'] = 'simple';
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->productplan->getPairsForStory($productID, $plan->branch, 'skipParent|withMainPlan');
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($plan->product, $plan->branch);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, $branch = 'all', $params = '');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->build->getBuildPairs($productID, $branch = 'all', $params = '');
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($productID, $branch = 'all', $params = 'releasetag');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($plan->product, 'bug', 0, $plan->branch);
|
||||
$this->config->bug->search['params']['project']['values'] = $this->product->getProjectPairsByProduct($productID, $plan->branch);
|
||||
|
||||
|
||||
@@ -1031,15 +1031,31 @@ class programModel extends model
|
||||
*/
|
||||
public function getTopPairs($model = '', $mode = '', $isQueryAll = false)
|
||||
{
|
||||
return $this->dao->select('id,name')->from(TABLE_PROGRAM)
|
||||
$topPairs = $this->dao->select('id,name')->from(TABLE_PROGRAM)
|
||||
->where('type')->eq('program')
|
||||
->andWhere('grade')->eq(1)
|
||||
->beginIF(strpos($mode, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi()
|
||||
->beginIF(!$isQueryAll)->andWhere('id')->in($this->app->user->view->programs)->fi()
|
||||
->andWhere('deleted')->eq(0)
|
||||
->beginIF(strpos($mode, 'withDeleted') === false)->andWhere('deleted')->eq(0)->fi()
|
||||
->beginIF($model)->andWhere('model')->eq($model)->fi()
|
||||
->orderBy('`order` asc')
|
||||
->fetchPairs();
|
||||
|
||||
if(strpos($mode, 'withDeleted') !== false)
|
||||
{
|
||||
$deletedTopPairs = $this->dao->select('id, name')->from(TABLE_PROGRAM)
|
||||
->where('type')->eq('program')
|
||||
->andWhere('grade')->eq(1)
|
||||
->andWhere('deleted')->eq(1)
|
||||
->fetchPairs();
|
||||
|
||||
foreach($topPairs as $id => $name)
|
||||
{
|
||||
if(isset($deletedTopPairs[$id])) $topPairs[$id] .= ' (' . $this->lang->program->deleted . ')';
|
||||
}
|
||||
}
|
||||
|
||||
return $topPairs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1462,6 +1462,7 @@ class project extends control
|
||||
{
|
||||
foreach($builds as $build)
|
||||
{
|
||||
$build->builds = $this->build->getByList($build->builds);
|
||||
/* If product is normal, unset branch name. */
|
||||
if(isset($productList[$build->product]) and $productList[$build->product]->type == 'normal')
|
||||
{
|
||||
@@ -1489,6 +1490,7 @@ class project extends control
|
||||
$this->view->products = $products;
|
||||
$this->view->allExecutions = $allExecutions;
|
||||
$this->view->executions = $executions;
|
||||
$this->view->buildPairs = $this->loadModel('build')->getBuildPairs(0);
|
||||
$this->view->type = $type;
|
||||
|
||||
$this->display();
|
||||
@@ -2167,6 +2169,11 @@ class project extends control
|
||||
}
|
||||
|
||||
$oldProducts = $this->product->getProducts($projectID);
|
||||
if($project->multiple and $project->model != 'waterfall')
|
||||
{
|
||||
$executions = $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq($projectID)->fetchPairs('id');
|
||||
$oldExecutionProducts = $this->dao->select('project,product')->from(TABLE_PROJECTPRODUCT)->where('project')->in($executions)->fetchGroup('project', 'product');
|
||||
}
|
||||
|
||||
$this->project->updateProducts($projectID);
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
@@ -2183,7 +2190,7 @@ class project extends control
|
||||
$diffProducts = array_merge(array_diff($oldProductIDs, $newProductIDs), array_diff($newProductIDs, $oldProductIDs));
|
||||
if($diffProducts) $this->loadModel('action')->create('project', $projectID, 'Managed', '', !empty($_POST['products']) ? join(',', $_POST['products']) : '');
|
||||
|
||||
if($project->multiple)
|
||||
if($project->multiple and $project->model != 'waterfall')
|
||||
{
|
||||
$unlinkedProducts = array_diff($oldProductIDs, $newProductIDs);
|
||||
if(!empty($unlinkedProducts))
|
||||
@@ -2191,8 +2198,14 @@ class project extends control
|
||||
$unlinkedProductPairs = array();
|
||||
foreach($unlinkedProducts as $unlinkedProduct) $unlinkedProductPairs[$unlinkedProduct] = $oldProducts[$unlinkedProduct]->name;
|
||||
|
||||
$executionIDList = $this->execution->getIdList($projectID);
|
||||
foreach($executionIDList as $executionID) $this->action->create('execution', $executionID, 'unlinkproduct', '', implode(',', $unlinkedProductPairs));
|
||||
$unlinkExecutions = array();
|
||||
foreach($oldExecutionProducts as $executionID => $executionProducts)
|
||||
{
|
||||
$unlinkExecutionProducts = array_intersect_key($unlinkedProductPairs, $executionProducts);
|
||||
if($unlinkExecutionProducts) $unlinkExecutions[$executionID] = $unlinkExecutionProducts;
|
||||
}
|
||||
|
||||
foreach($unlinkExecutions as $executionID => $unlinkExecutionProducts) $this->action->create('execution', $executionID, 'unlinkproduct', '', implode(',', $unlinkExecutionProducts));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2313,6 +2326,32 @@ class project extends control
|
||||
return print(html::select('execution', $executions, $executionID, "class='form-control'"));
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: get a project by execution id.
|
||||
*
|
||||
* @param string $executionID
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetPairsByExecution($executionID)
|
||||
{
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
$projectPairs = $this->loadModel('project')->getPairsByIdList($execution->project);
|
||||
|
||||
if($this->app->getViewType() == 'json')
|
||||
{
|
||||
$project = array('id' => key($projectPairs), 'name' => reset($projectPairs));
|
||||
$pinyin = common::convert2Pinyin(array(reset($projectPairs)));
|
||||
$project['namePinyin'] = zget($pinyin, $project['name']);
|
||||
|
||||
return print(json_encode($project));
|
||||
}
|
||||
else
|
||||
{
|
||||
return print(html::select('project', $projectPairs, $execution->project, "class='form-control' onchange='loadProductExecutions({$execution->project}, this.value)'"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Link projects and code repositories.
|
||||
*
|
||||
|
||||
@@ -27,3 +27,4 @@
|
||||
.futureBox {vertical-align: top !important; padding-top: 13px !important;}
|
||||
#projectType {padding-top: 7px !important;}
|
||||
.division .icon-help {margin-left: 15px}
|
||||
.has-info {border-color: #0c64eb!important;}
|
||||
@@ -374,3 +374,9 @@ $lang->project->action = new stdclass();
|
||||
$lang->project->action->managed = '$date, managed by <strong>$actor</strong>. $extra' . "\n";
|
||||
|
||||
$lang->project->multiple = "Multi {$lang->executionCommon}";
|
||||
|
||||
$lang->project->copyproject = new stdClass();
|
||||
$lang->project->copyproject->nameTips = '『Project Name』Cannot be repeated.';
|
||||
$lang->project->copyproject->codeTips = '『Project Code』Cannot be repeated.';
|
||||
$lang->project->copyproject->endTips = '『Schedule End』Cannot be empty.';
|
||||
$lang->project->copyproject->daysTips = '『Available working days』Should be numerical.';
|
||||
@@ -374,3 +374,9 @@ $lang->project->action = new stdclass();
|
||||
$lang->project->action->managed = '$date, managed by <strong>$actor</strong>. $extra' . "\n";
|
||||
|
||||
$lang->project->multiple = "Multi {$lang->executionCommon}";
|
||||
|
||||
$lang->project->copyproject = new stdClass();
|
||||
$lang->project->copyproject->nameTips = '『Project Name』Cannot be repeated.';
|
||||
$lang->project->copyproject->codeTips = '『Project Code』Cannot be repeated.';
|
||||
$lang->project->copyproject->endTips = '『Schedule End』Cannot be empty.';
|
||||
$lang->project->copyproject->daysTips = '『Available working days』Should be numerical.';
|
||||
@@ -374,3 +374,9 @@ $lang->project->action = new stdclass();
|
||||
$lang->project->action->managed = '$date, managed by <strong>$actor</strong>. $extra' . "\n";
|
||||
|
||||
$lang->project->multiple = "Multi {$lang->executionCommon}";
|
||||
|
||||
$lang->project->copyproject = new stdClass();
|
||||
$lang->project->copyproject->nameTips = '『Project Name』Cannot be repeated.';
|
||||
$lang->project->copyproject->codeTips = '『Project Code』Cannot be repeated.';
|
||||
$lang->project->copyproject->endTips = '『Schedule End』Cannot be empty.';
|
||||
$lang->project->copyproject->daysTips = '『Available working days』Should be numerical.';
|
||||
@@ -374,3 +374,9 @@ $lang->project->action = new stdclass();
|
||||
$lang->project->action->managed = '$date, 由 <strong>$actor</strong> 维护。$extra' . "\n";
|
||||
|
||||
$lang->project->multiple = "启用{$lang->executionCommon}";
|
||||
|
||||
$lang->project->copyproject = new stdClass();
|
||||
$lang->project->copyproject->nameTips = '『项目名称』不可重复需要修改。';
|
||||
$lang->project->copyproject->codeTips = '『项目代号』不可重复需要修改。';
|
||||
$lang->project->copyproject->endTips = '『计划完成』不能为空。';
|
||||
$lang->project->copyproject->daysTips = '『可用工作日』应当是数字。';
|
||||
@@ -2339,7 +2339,7 @@ class projectModel extends model
|
||||
$members = array_keys($this->getTeamMembers($projectID));
|
||||
|
||||
/* Link products of other programs. */
|
||||
if($_POST['otherProducts'])
|
||||
if(!empty($_POST['otherProducts']))
|
||||
{
|
||||
$products = array();
|
||||
$otherProducts = $_POST['otherProducts'];
|
||||
@@ -2424,9 +2424,10 @@ class projectModel extends model
|
||||
}
|
||||
|
||||
/* Delete the execution linked products that is not linked with the execution. */
|
||||
if((int)$projectID > 0)
|
||||
$projectID = (int)$projectID;
|
||||
if($projectID > 0)
|
||||
{
|
||||
$executions = $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq((int)$projectID)->fetchPairs('id');
|
||||
$executions = $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq($projectID)->fetchPairs('id');
|
||||
$this->dao->delete()->from(TABLE_PROJECTPRODUCT)->where('project')->in($executions)->andWhere('product')->notin($products)->exec();
|
||||
|
||||
if(!empty($_POST['division']))
|
||||
|
||||
@@ -81,7 +81,23 @@
|
||||
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
|
||||
<?php endif;?>
|
||||
<?php if($project->multiple):?>
|
||||
<?php if($build->execution):?>
|
||||
<td class="c-name text-left" title='<?php echo $build->executionName;?>'><?php echo $build->executionName;?></td>
|
||||
<?php else:?>
|
||||
<td class="c-name text-left">
|
||||
<?php $childExecutions = array();?>
|
||||
<?php foreach($build->builds as $childBuild):?>
|
||||
<?php $childExecutions[$childBuild->execution] = $childBuild->execution;?>
|
||||
<?php endforeach;?>
|
||||
|
||||
<?php foreach($childExecutions as $execution):?>
|
||||
<?php $executionName = zget($allExecutions, $execution, '');?>
|
||||
<?php if($executionName):?>
|
||||
<span title="<?php echo $executionName;?>"><?php echo $executionName;?></span></br>
|
||||
<?php endif;?>
|
||||
<?php endforeach;?>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
<td class="c-url" title="<?php echo $build->scmPath?>"><?php echo strpos($build->scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?></td>
|
||||
<td class="c-url" title="<?php echo $build->filePath?>"><?php echo strpos($build->filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?></td>
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
<?php js::set('ignore', $lang->project->ignore);?>
|
||||
<?php $requiredFields = $config->project->create->requiredFields;?>
|
||||
<?php js::set('requiredFields', $requiredFields);?>
|
||||
<?php js::set('copyType', '');?>
|
||||
<?php js::set('nameTips', $lang->project->copyproject->nameTips);?>
|
||||
<?php js::set('codeTips', $lang->project->copyproject->codeTips);?>
|
||||
<?php js::set('endTips', $lang->project->copyproject->endTips);?>
|
||||
<?php js::set('daysTips', $lang->project->copyproject->daysTips);?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
|
||||
@@ -69,7 +69,10 @@ class projectrelease extends control
|
||||
*/
|
||||
public function browse($projectID = 0, $executionID = 0, $type = 'all', $orderBy = 't1.date_desc', $recTotal = 0, $recPerPage = 15, $pageID = 1)
|
||||
{
|
||||
$this->session->set('releaseList', $this->app->getURI(true), 'project');
|
||||
$uri = $this->app->getURI(true);
|
||||
$this->session->set('releaseList', $uri, 'project');
|
||||
$this->session->set('buildList', $uri);
|
||||
|
||||
$project = $this->project->getById($projectID);
|
||||
$execution = $this->loadModel('execution')->getById($executionID);
|
||||
|
||||
@@ -130,17 +133,17 @@ class projectrelease extends control
|
||||
$this->commonAction($projectID);
|
||||
|
||||
/* Get the builds that can select. */
|
||||
$builds = $this->build->getBuildPairs($this->view->product->id, $this->view->branch, 'notrunk,withbranch|hasproject', $projectID, 'project');
|
||||
$builds = $this->build->getBuildPairs($this->view->product->id, $this->view->branch, 'notrunk|withbranch|hasproject', $projectID, 'project', '', false);
|
||||
$releasedBuilds = $this->projectrelease->getReleasedBuilds($projectID);
|
||||
foreach($releasedBuilds as $build) unset($builds[$build]);
|
||||
unset($builds['trunk']);
|
||||
|
||||
$this->view->title = $this->view->project->name . $this->lang->colon . $this->lang->release->create;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->builds = $builds;
|
||||
$this->view->lastRelease = $this->projectrelease->getLast($projectID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
|
||||
$this->view->confirmLink = $this->lang->release->confirmLink;
|
||||
$this->view->title = $this->view->project->name . $this->lang->colon . $this->lang->release->create;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->builds = $builds;
|
||||
$this->view->lastRelease = $this->projectrelease->getLast($projectID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
|
||||
$this->view->confirmLink = $this->lang->release->confirmLink;
|
||||
$this->view->notEmptyBuilds = $this->build->filterLinked(array_keys($builds));
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -187,7 +190,7 @@ class projectrelease extends control
|
||||
$bindBuilds = $this->build->getByList($release->build);
|
||||
|
||||
/* Get the builds that can select. */
|
||||
$builds = $this->build->getBuildPairs($release->product, $release->branch, 'notrunk|withbranch|hasproject', $this->session->project, 'project', '', false);
|
||||
$builds = $this->build->getBuildPairs($release->product, $release->branch, 'notrunk|withbranch|hasproject', $this->session->project, 'project', $release->build, false);
|
||||
$releasedBuilds = $this->projectrelease->getReleasedBuilds($this->session->project);
|
||||
foreach($releasedBuilds as $releasedBuild)
|
||||
{
|
||||
@@ -196,7 +199,6 @@ class projectrelease extends control
|
||||
if(!isset($bindBuilds[$bindBuildID])) unset($builds[$bindBuildID]);
|
||||
}
|
||||
}
|
||||
unset($builds['trunk']);
|
||||
|
||||
/* Set project menu. */
|
||||
$this->project->setMenu($this->session->project);
|
||||
@@ -226,9 +228,6 @@ class projectrelease extends control
|
||||
*/
|
||||
public function view($releaseID, $type = 'story', $link = 'false', $param = '', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
{
|
||||
$this->session->set('buildList', $this->app->getURI(true), 'execution');
|
||||
$this->session->set('storyList', $this->app->getURI(true), $this->app->tab);
|
||||
|
||||
$this->loadModel('story');
|
||||
$this->loadModel('bug');
|
||||
|
||||
@@ -243,6 +242,11 @@ class projectrelease extends control
|
||||
return print(js::error($this->lang->notFound) . js::locate('back'));
|
||||
}
|
||||
|
||||
$uri = $this->app->getURI(true);
|
||||
if($release->build) $this->session->set('buildList', $uri);
|
||||
if($type == 'story') $this->session->set('storyList', $uri, $this->app->tab);
|
||||
if($type == 'bug' or $type == 'leftBug') $this->session->set('bugList', $uri, $this->app->tab);
|
||||
|
||||
$sort = common::appendOrder($orderBy);
|
||||
if(strpos($sort, 'pri_') !== false) $sort = str_replace('pri_', 'priOrder_', $sort);
|
||||
|
||||
@@ -683,7 +687,7 @@ class projectrelease extends control
|
||||
$this->config->bug->search['style'] = 'simple';
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan');
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($release->product, $release->branch, 'id_desc', $release->project);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 0, $params = '');
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 0);
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
|
||||
$searchModules = array();
|
||||
@@ -811,8 +815,10 @@ class projectrelease extends control
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'notrunk,withbranch,hasproject', $projectID, 'project', '', false);
|
||||
$releasedBuilds = $this->projectrelease->getReleasedBuilds($projectID);
|
||||
foreach($releasedBuilds as $build) unset($builds[$build]);
|
||||
unset($builds['trunk']);
|
||||
|
||||
return print(html::select('build[]', $builds, '', "class='form-control chosen' multiple"));
|
||||
/* Get the builds of the linked stories or bugs. */
|
||||
$notEmptyBuilds = $this->build->filterLinked(array_keys($builds));
|
||||
|
||||
return print(html::select('build[]', $builds, '', "class='form-control chosen' multiple data-notemptybuilds='" . join(',', $notEmptyBuilds) . "'"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
$('#submit').click(function()
|
||||
{
|
||||
var dateFormat = new RegExp(/^\d{4}\-\d{2}\-\d{2}$/);
|
||||
var name = $('#name').val();
|
||||
var date = $('#date').val();
|
||||
var build = $('#build').val();
|
||||
if(name && build && dateFormat.test(date))
|
||||
var dateFormat = new RegExp(/^\d{4}\-\d{2}\-\d{2}$/);
|
||||
var name = $('#name').val();
|
||||
var date = $('#date').val();
|
||||
var build = $('#build').val();
|
||||
var notEmptyBuild = false;
|
||||
|
||||
$.each(build, function(index, value)
|
||||
{
|
||||
if(typeof(notEmptyBuilds[value]) != 'undefined')
|
||||
{
|
||||
notEmptyBuild = true;
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
if(name && build && notEmptyBuild && dateFormat.test(date))
|
||||
{
|
||||
var result = confirm(confirmLink) ? true : false;
|
||||
$('#sync').val(result);
|
||||
}
|
||||
});
|
||||
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
/**
|
||||
* Ajax load unlinked builds with project and product.
|
||||
*
|
||||
@@ -26,6 +35,10 @@ function loadBuilds()
|
||||
$('#buildBox').load(createLink('projectrelease', 'ajaxLoadBuilds', "projectID=" + projectID + "&productID=" + productID + "&branch=" + branch), function()
|
||||
{
|
||||
$('#build').attr('data-placeholder', multipleSelect).chosen();
|
||||
$.each($('#build').attr('data-notemptybuilds').split(','), function(index, value)
|
||||
{
|
||||
notEmptyBuilds[value] = value;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php js::set('confirmLink', $confirmLink);?>
|
||||
<?php js::set('notEmptyBuilds', $notEmptyBuilds);?>
|
||||
<?php js::set('projectID', $projectID);?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
<table class='table table-data'>
|
||||
<?php if($project->hasProduct):?>
|
||||
<tr>
|
||||
<th class='w-90px'><?php echo $lang->release->product;?></th>
|
||||
<th class='w-100px'><?php echo $lang->release->product;?></th>
|
||||
<td><?php echo $release->productName;?></td>
|
||||
</tr>
|
||||
<?php if($release->productType != 'normal'):?>
|
||||
|
||||
+10
-26
@@ -46,7 +46,10 @@ class release extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
$this->commonAction($productID, $branch);
|
||||
$this->session->set('releaseList', $this->app->getURI(true), 'product');
|
||||
|
||||
$uri = $this->app->getURI(true);
|
||||
$this->session->set('releaseList', $uri, 'product');
|
||||
$this->session->set('buildList', $uri);
|
||||
|
||||
$this->view->title = $this->view->product->name . $this->lang->colon . $this->lang->release->browse;
|
||||
$this->view->position[] = $this->lang->release->browse;
|
||||
@@ -86,27 +89,6 @@ class release extends control
|
||||
$releasedBuilds = $this->release->getReleasedBuilds($productID, $branch);
|
||||
foreach($releasedBuilds as $build) unset($builds[$build]);
|
||||
|
||||
/* Get the builds of the linked stories or bugs. */
|
||||
$notEmptyBuilds = array();
|
||||
$buildList = $this->build->getByList(array_keys($builds));
|
||||
foreach($buildList as $build)
|
||||
{
|
||||
if(!$build->execution && !empty($build->builds))
|
||||
{
|
||||
$childBuilds = $this->build->getByList($build->builds);
|
||||
foreach($childBuilds as $childBuild)
|
||||
{
|
||||
$childBuild->stories = trim($childBuild->stories, ',');
|
||||
$childBuild->bugs = trim($childBuild->bugs, ',');
|
||||
|
||||
if($childBuild->stories) $build->stories .= ',' . $childBuild->stories;
|
||||
if($childBuild->bugs) $build->bugs .= ',' . $childBuild->bugs;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($build->stories) or !empty($build->bugs)) $notEmptyBuilds[$build->id] = $build->id;
|
||||
}
|
||||
|
||||
$this->commonAction($productID, $branch);
|
||||
$this->view->title = $this->view->product->name . $this->lang->colon . $this->lang->release->create;
|
||||
$this->view->position[] = $this->lang->release->create;
|
||||
@@ -114,7 +96,7 @@ class release extends control
|
||||
$this->view->builds = $builds;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
|
||||
$this->view->lastRelease = $this->release->getLast($productID, $branch);
|
||||
$this->view->notEmptyBuilds = $notEmptyBuilds;
|
||||
$this->view->notEmptyBuilds = $this->build->filterLinked(array_keys($builds));
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -188,8 +170,10 @@ class release extends control
|
||||
$release = $this->release->getByID($releaseID, true);
|
||||
if(!$release) return print(js::error($this->lang->notFound) . js::locate($this->createLink('product', 'index')));
|
||||
|
||||
if($type == 'story') $this->session->set('storyList', $this->app->getURI(true), 'product');
|
||||
if($type == 'bug' or $type == 'leftBug') $this->session->set('bugList', $this->app->getURI(true), 'qa');
|
||||
$uri = $this->app->getURI(true);
|
||||
if(!empty($release->build)) $this->session->set('buildList', $uri);
|
||||
if($type == 'story') $this->session->set('storyList', $uri, 'product');
|
||||
if($type == 'bug' or $type == 'leftBug') $this->session->set('bugList', $uri, 'qa');
|
||||
|
||||
$this->loadModel('story');
|
||||
$this->loadModel('bug');
|
||||
@@ -639,7 +623,7 @@ class release extends control
|
||||
|
||||
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairsForStory($release->product, $release->branch, 'skipParent|withMainPlan');
|
||||
$this->config->bug->search['params']['execution']['values'] = $this->loadModel('product')->getExecutionPairsByProduct($release->product, $release->branch);
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 'all', $params = '');
|
||||
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($release->product, $branch = 'all', 'releasetag');
|
||||
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
|
||||
|
||||
$searchModules = array();
|
||||
|
||||
@@ -21,5 +21,3 @@ $('#submit').click(function()
|
||||
$('#sync').val(result);
|
||||
}
|
||||
});
|
||||
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
@@ -123,12 +123,13 @@ class releaseModel extends model
|
||||
$buildIdList = array();
|
||||
foreach($releases as $release)
|
||||
{
|
||||
if($branch != 'all')
|
||||
if($branch != 'all' and $branch !== '')
|
||||
{
|
||||
$inBranch = false;
|
||||
foreach(explode(',', trim($release->branch, ',')) as $branchID)
|
||||
{
|
||||
if(empty($branchID)) continue;
|
||||
if($branchID === '') continue;
|
||||
|
||||
if(strpos(",{$branch},", ",{$branchID},") !== false) $inBranch = true;
|
||||
}
|
||||
if(!$inBranch) continue;
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
<div class='detail-content'>
|
||||
<table class='table table-data'>
|
||||
<tr>
|
||||
<th class='w-90px'><?php echo $lang->release->product;?></th>
|
||||
<th class='w-100px'><?php echo $lang->release->product;?></th>
|
||||
<td><?php echo $release->productName;?></td>
|
||||
</tr>
|
||||
<?php if($release->productType != 'normal'):?>
|
||||
|
||||
@@ -246,6 +246,7 @@ $lang->task->confirmRecord = '"Reststunden " sind 0. Möchten Sie de
|
||||
$lang->task->confirmTransfer = '"Left Hour" is 0,Do you want to assign to <strong>%s</strong> task?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "Es wurde keine Story verknüpft. Sie können %s für dieses Projekt, anschließend %s.";
|
||||
$lang->task->noticeLinkStoryNoProduct = "No story has been linked.";
|
||||
$lang->task->noticeSaveRecord = 'Ihre Stunden wurden nicht gespeichrt. Bitte erst speichern.';
|
||||
$lang->task->noticeManageTeam = 'Task status is %s, can not manage team.';
|
||||
$lang->task->commentActions = '%s. %s, kommentiert von <strong>%s</strong>.';
|
||||
|
||||
@@ -246,6 +246,7 @@ $lang->task->confirmRecord = '"Left Hour" is 0. Do you want to set t
|
||||
$lang->task->confirmTransfer = '"Left Hour" is 0,Do you want to assign to <strong>%s</strong> task?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "No story has been linked. You can %s for this project, then %s.";
|
||||
$lang->task->noticeLinkStoryNoProduct = "No story has been linked.";
|
||||
$lang->task->noticeSaveRecord = 'Your Hour is not saved. Please save it first.';
|
||||
$lang->task->noticeManageTeam = 'Task status is %s, can not manage team.';
|
||||
$lang->task->commentActions = '%s. %s, commented by <strong>%s</strong>.';
|
||||
|
||||
@@ -246,6 +246,7 @@ $lang->task->confirmRecord = '"Heures Restantes" à 0. Voulez-vous p
|
||||
$lang->task->confirmTransfer = '"Left Hour" is 0,Do you want to assign to <strong>%s</strong> task?';
|
||||
$lang->task->noticeTaskStart = '"Cost Hour" and "Left Hour" cannot be 0 at the same time.';
|
||||
$lang->task->noticeLinkStory = "Aucune Story n'est associée. Vous pouvez %s pour ce projet, alors %s.";
|
||||
$lang->task->noticeLinkStoryNoProduct = "No story has been linked.";
|
||||
$lang->task->noticeSaveRecord = "Votre temps n'a pas été sauvé. Enregistrez-le d'abord.";
|
||||
$lang->task->noticeManageTeam = 'Task status is %s, can not manage team.';
|
||||
$lang->task->commentActions = '%s. %s, commenté par <strong>%s</strong>.';
|
||||
|
||||
@@ -246,6 +246,7 @@ $lang->task->confirmRecord = '"剩余"为0,任务将标记为"已
|
||||
$lang->task->confirmTransfer = '剩余工时为0,当前成员已完成任务,任务指派给:<strong>%s</strong>。';
|
||||
$lang->task->noticeTaskStart = '"总计消耗"和"预计剩余"不能同时为0';
|
||||
$lang->task->noticeLinkStory = "没有可关联的相关{$lang->SRCommon},您可以为当前项目%s,然后%s";
|
||||
$lang->task->noticeLinkStoryNoProduct = "没有可关联的相关{$lang->SRCommon}";
|
||||
$lang->task->noticeSaveRecord = '您有尚未保存的工时记录,请先将其保存。';
|
||||
$lang->task->noticeManageTeam = '任务状态是%s,不能维护团队';
|
||||
$lang->task->commentActions = '%s. %s, 由 <strong>%s</strong> 添加备注。';
|
||||
|
||||
+34
-2
@@ -3215,6 +3215,16 @@ class taskModel extends model
|
||||
$task->progress = round($task->consumed / ($task->consumed + $task->left), 2) * 100;
|
||||
}
|
||||
|
||||
if($task->mode == 'multi')
|
||||
{
|
||||
$teamMembers = $this->dao->select('t1.realname')->from(TABLE_USER)->alias('t1')
|
||||
->leftJoin(TABLE_TASKTEAM)->alias('t2')
|
||||
->on('t1.account = t2.account')
|
||||
->where('t2.task')->eq($task->id)
|
||||
->fetchPairs();
|
||||
$task->teamMembers= join(',', array_keys($teamMembers));
|
||||
}
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
@@ -3930,8 +3940,15 @@ class taskModel extends model
|
||||
public function getToAndCcList($task)
|
||||
{
|
||||
/* Set toList and ccList. */
|
||||
$toList = $task->assignedTo;
|
||||
$ccList = trim($task->mailto, ',');
|
||||
$toList = $task->assignedTo;
|
||||
$ccList = trim($task->mailto, ',');
|
||||
$toTeamTaskList = '';
|
||||
if($task->mode == 'multi')
|
||||
{
|
||||
$toTeamTaskList = $this->getTeamMembers($task->id);
|
||||
$toTeamTaskList = implode(',', $toTeamTaskList);
|
||||
$toList = $toTeamTaskList;
|
||||
}
|
||||
|
||||
if(empty($toList))
|
||||
{
|
||||
@@ -4348,4 +4365,19 @@ class taskModel extends model
|
||||
$order ++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get teamTask members.
|
||||
*
|
||||
* @param int $taskID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTeamMembers($taskID)
|
||||
{
|
||||
$taskType = $this->dao->select('mode')->from(TABLE_TASK)->where('id')->eq($taskID)->fetch('mode');
|
||||
if($taskType != 'multi') return array();
|
||||
$teamMembers = $this->dao->select('account')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->fetchPairs();
|
||||
return empty($teamMembers) ? $teamMembers : array_keys($teamMembers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,13 @@ foreach(explode(',', $config->task->create->requiredFields) as $field)
|
||||
<tr class="<?php echo $hiddenStory?> storyBox">
|
||||
<th><?php echo $lang->task->story;?></th>
|
||||
<td colspan='3'>
|
||||
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->id"), $lang->execution->linkStory, '', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
|
||||
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> ">
|
||||
<?php
|
||||
$noticeLinkStory = sprintf($lang->task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->id"), $lang->execution->linkStory, '', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));
|
||||
if(empty($execution->hasProduct)) $noticeLinkStory = $lang->task->noticeLinkStoryNoProduct;
|
||||
echo $noticeLinkStory;
|
||||
?>
|
||||
</span>
|
||||
<div class='input-group <?php if(empty($stories)) echo "hidden";?>'>
|
||||
<?php echo html::select('story', $stories, $task->story, "class='form-control chosen' onchange='setStoryRelated();'");?>
|
||||
<?php if(common::hasPriv('execution', 'storyView')):?>
|
||||
|
||||
@@ -250,7 +250,7 @@ class testtask extends control
|
||||
/* Create testtask from testtask of test.*/
|
||||
$productID = $productID ? $productID : key($this->products);
|
||||
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID, 'stagefilter');
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk');
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk,withexecution', $projectID, 'project');
|
||||
|
||||
$execution = $this->loadModel('execution')->getByID($executionID);
|
||||
if(!empty($execution) and $execution->type == 'kanban') $this->lang->testtask->execution = str_replace($this->lang->execution->common, $this->lang->kanban->common, $this->lang->testtask->execution);
|
||||
@@ -816,13 +816,18 @@ class testtask extends control
|
||||
$executions[$executionID] = $project->name . "({$this->lang->project->disableExecution})";
|
||||
}
|
||||
}
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk,withexecution', $executionID, 'execution');
|
||||
}
|
||||
else
|
||||
{
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk,withexecution', $task->project, 'project');
|
||||
}
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->edit;
|
||||
$this->view->task = $task;
|
||||
$this->view->project = $this->project->getByID($projectID);
|
||||
$this->view->executions = $executions;
|
||||
$this->view->builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,notrunk', $executionID, 'execution');
|
||||
$this->view->builds = empty($productID) ? array() : $builds;
|
||||
$this->view->testreports = $this->loadModel('testreport')->getPairs($task->product, $task->testreport);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed', $task->owner);
|
||||
$this->view->contactLists = $this->user->getContactLists($this->app->user->account, 'withnote');
|
||||
@@ -1421,7 +1426,7 @@ class testtask extends control
|
||||
$this->view->case = $case;
|
||||
$this->view->runID = $runID;
|
||||
$this->view->results = $results;
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($case->product, $case->branch, $params = '');
|
||||
$this->view->builds = $this->loadModel('build')->getBuildPairs($case->product, $case->branch);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed, noletter');
|
||||
|
||||
$this->display();
|
||||
@@ -1491,7 +1496,7 @@ class testtask extends control
|
||||
|
||||
$projectID = $this->app->tab == 'qa' ? 0 : $this->session->project;
|
||||
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk');
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk', 0, 'execution', '', false);
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->importUnitResult;
|
||||
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
@@ -1501,6 +1506,7 @@ class testtask extends control
|
||||
$this->view->builds = $builds;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted|noclosed');
|
||||
$this->view->productID = $productID;
|
||||
$this->view->projectID = $projectID;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -90,21 +90,18 @@ function loadExecutionRelated(executionID)
|
||||
* Load execution builds.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param int $selected
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function loadExecutionBuilds(executionID, selected)
|
||||
function loadExecutionBuilds(executionID)
|
||||
{
|
||||
var selectedBuild = $('#build').val();
|
||||
|
||||
if(!selectedBuild) selectedBuild = 0;
|
||||
var link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + $('#product').val() + '&varName=testTaskBuild&build=' + selectedBuild);
|
||||
if(executionID == 0) link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + $('#product').val() + '&varName=resolvedBuild&build=' + selectedBuild);
|
||||
if(executionID == 0) link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + $('#product').val() + '&varName=build&build=' + selectedBuild + '&branch=&index=&needCreate=&type=noempty,notrunk,withexecution');
|
||||
$('#buildBox').load(link, function()
|
||||
{
|
||||
$('#resolvedBuild').attr('id', 'build').attr('name', 'build').find('option[value=trunk]').remove();
|
||||
if(selected) $('#build').val(selected);
|
||||
$('#build').chosen();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,11 +8,7 @@ function loadProductRelated()
|
||||
{
|
||||
loadExecutions($('#product').val());
|
||||
loadTestReports($('#product').val());
|
||||
buildData = '<select id="build" name="build" class="form-control"></select>';
|
||||
$('#build').replaceWith(buildData);
|
||||
$('#build_chosen').remove();
|
||||
$("#build").chosen();
|
||||
$('#build').trigger("chosen:updated");
|
||||
loadExecutionBuilds($('#execution').val())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,12 +20,14 @@ function loadProductRelated()
|
||||
*/
|
||||
function loadExecutions(productID)
|
||||
{
|
||||
var executionID = $('#execution').val();
|
||||
link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID + '&branch=');
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="execution" name="execution" class="form-control"></select>';
|
||||
$('#execution').replaceWith(data);
|
||||
$('#execution_chosen').remove();
|
||||
$("#execution").val(executionID);
|
||||
$("#execution").chosen();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,12 +38,11 @@
|
||||
<?php if(isset($noMultipleExecutionID)):?>
|
||||
<?php echo html::hidden('execution', $noMultipleExecutionID);?>
|
||||
<?php else:?>
|
||||
<tr>
|
||||
<tr class='<?php echo ($app->tab == 'execution' and $executionID) ? 'hide' : '';?>'>
|
||||
<th class='w-100px'><?php echo $lang->testtask->execution;?></th>
|
||||
<td class='w-p35-f'><?php echo html::select('execution', $executions, $executionID, "class='form-control chosen' onchange='loadExecutionRelated(this.value)'");?></td><td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->testtask->build;?></th>
|
||||
<td>
|
||||
@@ -58,7 +57,6 @@
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th><?php echo $lang->testtask->type;?></th>
|
||||
<td><?php echo html::select('type[]', $lang->testtask->typeList, '', "class='form-control picker-select' multiple");?></td>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/datepicker.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<?php js::set('projectID', $task->project);?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
@@ -24,16 +25,18 @@
|
||||
</div>
|
||||
<form method='post' class="main-form form-ajax" enctype="multipart/form-data" id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr class="<?php if(isset($project) and !$project->multiple) echo 'hide';?>">
|
||||
<?php echo html::hidden('product', $task->product);?>
|
||||
<?php if(!empty($project) and !$project->multiple):?>
|
||||
<?php echo html::hidden('execution', $task->execution);?>
|
||||
<?php else:?>
|
||||
<tr class='<?php echo ($app->tab == 'execution' and $task->execution) ? 'hide' : '';?>'>
|
||||
<th class='w-100px'><?php echo $lang->testtask->execution;?></th>
|
||||
<td class='w-p35-f'>
|
||||
<?php
|
||||
echo html::select('execution', $executions, $task->execution, "class='form-control chosen' onchange='loadExecutionRelated(this.value)'");
|
||||
echo html::hidden('product', $task->product);
|
||||
?>
|
||||
<?php echo html::select('execution', $executions, $task->execution, "class='form-control chosen' onchange='loadExecutionRelated(this.value)'");?>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th class='w-100px'><?php echo $lang->testtask->build;?></th>
|
||||
<td class='w-p35-f'><span id='buildBox'><?php echo html::select('build', $builds, $task->build, "class='form-control chosen'");?></span></td>
|
||||
|
||||
@@ -107,4 +107,5 @@ $(function()
|
||||
$('#subNavbar li[data-id="case"]').addClass('active');
|
||||
})
|
||||
</script>
|
||||
<?php js::set('projectID', $projectID);?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -425,10 +425,9 @@ class treeModel extends model
|
||||
|
||||
$this->loadModel('branch');
|
||||
$projectID = zget($extra, 'projectID', 0);
|
||||
$executionID = zget($extra, 'executionID', 0);
|
||||
$branches = array($branch => '');
|
||||
$executionModules = array();
|
||||
if($branch and empty($projectID) and empty($executionID))
|
||||
if($branch and empty($projectID))
|
||||
{
|
||||
$branchName = $this->branch->getById($branch);
|
||||
$branches = array($branch => $branchName);
|
||||
@@ -438,15 +437,15 @@ class treeModel extends model
|
||||
$manage = $userFunc[1] == 'createManageLink' ? true : false;
|
||||
$product = $this->loadModel('product')->getById($rootID);
|
||||
|
||||
$onlyGetLinked = (($projectID or $executionID) and $this->config->vision != 'lite');
|
||||
if(strpos('story|bug|case', $type) !== false and $branch === 'all' and empty($projectID) and empty($executionID))
|
||||
$onlyGetLinked = ($projectID and $this->config->vision != 'lite');
|
||||
if(strpos('story|bug|case', $type) !== false and $branch === 'all' and empty($projectID))
|
||||
{
|
||||
if($product->type != 'normal') $branches = array(BRANCH_MAIN => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($rootID, 'noempty');
|
||||
}
|
||||
elseif(strpos(',case,bug,', ",$type,") !== false and $this->app->tab == 'execution')
|
||||
{
|
||||
if($product->type != 'normal' and $executionID) $branches += $this->branch->getPairs($product->id, 'noempty', $executionID);
|
||||
if($onlyGetLinked) $executionModules = $this->getTaskTreeModules($executionID, true, $type, array('branchID' => $branch));
|
||||
if($product->type != 'normal' and $projectID) $branches += $this->branch->getPairs($product->id, 'noempty', $projectID);
|
||||
if($onlyGetLinked) $executionModules = $this->getTaskTreeModules($projectID, true, $type, array('branchID' => $branch));
|
||||
}
|
||||
elseif(($type == 'story' and $this->app->rawModule == 'projectstory') or (strpos(',case,bug,', ",$type,") !== false and $this->app->tab == 'project'))
|
||||
{
|
||||
@@ -1259,7 +1258,7 @@ class treeModel extends model
|
||||
$param = "root={$module->root}&branch=&type=byModule¶m={$module->id}";
|
||||
|
||||
$extra['type'] = (isset($extra['type']) and $extra['type'] != 'bysearch') ? $extra['type'] : 'all';
|
||||
if($this->app->tab == 'execution') $param = "execuitonID={$extra['executionID']}&productID={$module->root}&branch={$extra['branchID']}&orderBy={$extra['orderBy']}&build={$extra['build']}&type={$extra['type']}¶m={$module->id}";
|
||||
if($this->app->tab == 'execution') $param = "execuitonID={$extra['projectID']}&productID={$module->root}&branch={$extra['branchID']}&orderBy={$extra['orderBy']}&build={$extra['build']}&type={$extra['type']}¶m={$module->id}";
|
||||
if($this->app->tab == 'project') $param = "projectID={$extra['projectID']}&productID={$module->root}&branch={$extra['branchID']}&orderBy={$extra['orderBy']}&build={$extra['build']}&type={$extra['type']}¶m={$module->id}";
|
||||
return html::a(helper::createLink($moduleName, $methodName, $param), $module->name, '_self', "id='module{$module->id}' title='{$module->name}'");
|
||||
}
|
||||
@@ -1278,7 +1277,7 @@ class treeModel extends model
|
||||
$moduleName = strpos(',project,execution,', ",{$this->app->tab},") !== false ? $this->app->tab : 'testcase';
|
||||
$methodName = strpos(',project,execution,', ",{$this->app->tab},") !== false ? 'testcase' : 'browse';
|
||||
$param = $this->app->tab == 'project' ? "projectID={$this->session->project}&" : "";
|
||||
$param = $this->app->tab == 'execution' ? "executionID={$extra['executionID']}&" : $param;
|
||||
$param = $this->app->tab == 'execution' ? "executionID={$extra['projectID']}&" : $param;
|
||||
return html::a(helper::createLink($moduleName, $methodName, $param . "root={$module->root}&branch={$extra['branchID']}&type=byModule¶m={$module->id}"), $module->name, '_self', "id='module{$module->id}' data-app='{$this->app->tab}' title='{$module->name}'");
|
||||
}
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ class upgradeModel extends model
|
||||
$this->updateProjectLinkedBranch();
|
||||
break;
|
||||
case '16_0_beta1':
|
||||
$this->loadModel('api')->createDemoData($this->lang->api->zentaoAPI, 'http://' . $_SERVER['HTTP_HOST'] . $this->app->config->webRoot . 'api.php/v1', '16.0');
|
||||
$this->loadModel('api')->createDemoData($this->lang->api->zentaoAPI, commonModel::getSysURL() . $this->app->config->webRoot . 'api.php/v1', '16.0');
|
||||
break;
|
||||
case '16_1':
|
||||
$this->moveKanbanData();
|
||||
@@ -4287,7 +4287,7 @@ class upgradeModel extends model
|
||||
$moduleRoot = $this->app->getModuleRoot();
|
||||
|
||||
$editorDir = $moduleRoot . 'editor';
|
||||
if(is_dir($editor)) $zfile->removeDir($editorDir);
|
||||
if(is_dir($editorDir)) $zfile->removeDir($editorDir);
|
||||
|
||||
$translateDir = $moduleRoot . 'translate';
|
||||
if(is_dir($translateDir)) $zfile->removeDir($translateDir);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<?php endif;?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endForeach;?>
|
||||
<?php endforeach;?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -149,6 +149,20 @@ class buildTest
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for filterLinked method
|
||||
*
|
||||
* @param array $buildIdList
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function filterLinkedTest($buildIdList)
|
||||
{
|
||||
$notEmptyBuilds = $this->objectModel->filterLinked($buildIdList);
|
||||
sort($notEmptyBuilds);
|
||||
return empty($notEmptyBuilds) ? 'null' : join(',', $notEmptyBuilds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function getLast test by build
|
||||
*
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/build.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 buildModel->filterLinked();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
不传任何数据 >> null
|
||||
迭代版本未关联需求和Bug >> null
|
||||
迭代版本关联需求和Bug >> 101
|
||||
项目版本关联版本关联需求和Bug >> 102
|
||||
项目版本关联版本未关联需求和Bug >> null
|
||||
版本列表中关联需求和Bug >> 101
|
||||
版本列表中混合项目版本和迭代版本 >> 101,102
|
||||
|
||||
*/
|
||||
|
||||
$build = new buildTest();
|
||||
|
||||
$buildData = new stdclass();
|
||||
$buildData->id = 100;
|
||||
$buildData->product = 1;
|
||||
$buildData->project = 1;
|
||||
$buildData->execution = 2;
|
||||
$buildData->name = 'test1';
|
||||
$buildData->date = date('Y-m-d');
|
||||
$build->objectModel->dao->replace(TABLE_BUILD)->data($buildData)->exec();
|
||||
$buildId1 = $buildData->id;
|
||||
|
||||
$buildData->id = 101;
|
||||
$buildData->name = 'test2';
|
||||
$buildData->stories = '1,2,3';
|
||||
$build->objectModel->dao->replace(TABLE_BUILD)->data($buildData)->exec();
|
||||
$buildId2 = $buildData->id;
|
||||
|
||||
$buildData = new stdclass();
|
||||
$buildData->id = 102;
|
||||
$buildData->product = 1;
|
||||
$buildData->project = 1;
|
||||
$buildData->execution = 0;
|
||||
$buildData->builds = ",$buildId2,";
|
||||
$buildData->name = 'test3';
|
||||
$buildData->date = date('Y-m-d');
|
||||
$build->objectModel->dao->replace(TABLE_BUILD)->data($buildData)->exec();
|
||||
$buildId3 = $buildData->id;
|
||||
|
||||
$buildData = new stdclass();
|
||||
$buildData->id = 103;
|
||||
$buildData->product = 1;
|
||||
$buildData->project = 1;
|
||||
$buildData->execution = 0;
|
||||
$buildData->builds = ",$buildId1,";
|
||||
$buildData->name = 'test4';
|
||||
$buildData->date = date('Y-m-d');
|
||||
$build->objectModel->dao->replace(TABLE_BUILD)->data($buildData)->exec();
|
||||
$buildId4 = $buildData->id;
|
||||
|
||||
|
||||
r($build->filterLinkedTest(array())) && p() && e('null'); //不传任何数据
|
||||
r($build->filterLinkedTest(array($buildId1))) && p() && e('null'); //迭代版本未关联需求和Bug
|
||||
r($build->filterLinkedTest(array($buildId2))) && p() && e('101'); //迭代版本关联需求和Bug
|
||||
r($build->filterLinkedTest(array($buildId3))) && p() && e('102'); //项目版本关联版本关联需求和Bug
|
||||
r($build->filterLinkedTest(array($buildId4))) && p() && e('null'); //项目版本关联版本未关联需求和Bug
|
||||
r($build->filterLinkedTest(array($buildId1, $buildId2))) && p() && e('101'); //版本列表中关联需求和Bug
|
||||
r($build->filterLinkedTest(array($buildId3, $buildId2))) && p() && e('101,102'); //版本列表中混合项目版本和迭代版本
|
||||
Reference in New Issue
Block a user