Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/master_lanzongjun_fixbug

This commit is contained in:
lanzongjun
2022-11-18 14:07:23 +08:00
65 changed files with 373 additions and 157 deletions
-10
View File
@@ -1,14 +1,4 @@
<?php
$config->url = new stdclass();
$config->url->community = 'https://www.zentao.net';
$config->url->ask = 'https://www.zentao.net/ask-browse.html';
$config->url->document = 'https://www.zentao.net/help-book-zentaopmshelp.html';
$config->url->feedback = 'https://www.zentao.net/forum-board-1074.html';
$config->url->faq = 'https://www.zentao.net/ask-faq.html';
$config->url->extension = 'https://www.zentao.net/extension-browse.html';
$config->url->donation = 'https://www.zentao.net/help-donation.html';
$config->url->service = 'https://www.cnezsoft.com/article-browse-1078.html';
$config->admin->apiRoot = 'https://www.zentao.net';
$config->admin->log = new stdclass();
+4 -3
View File
@@ -337,11 +337,12 @@ class backup extends control
{
$this->app->loadLang('extension');
$search = dirname($this->app->getBasePath()) . DS;
$search = $this->app->getBasePath();
$pos = strpos($statusFile, $search);
if($pos !== false) $statusFile = substr_replace($statusFile, '', $pos, strlen($search));
$okFile = $statusFile;
if($pos !== false) $okFile = substr_replace($statusFile, '', $pos, strlen($search));
$this->view->error = sprintf($this->lang->extension->noticeOkFile, $statusFile, $statusFile);
$this->view->error = sprintf($this->lang->extension->noticeOkFile, $okFile, $statusFile);
return print($this->display());
}
+16 -19
View File
@@ -54,7 +54,7 @@ class build extends control
if(defined('TUTORIAL')) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true)); // Fix bug #21095.
$buildID = $this->build->create($executionID, $projectID);
$buildID = $this->build->create();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->loadModel('action')->create('build', $buildID, 'opened');
@@ -72,6 +72,8 @@ class build extends control
if($this->app->tab == 'project')
{
$this->project->setMenu($projectID);
$executions = $this->execution->getPairs($projectID, 'all', 'stagefilter');
$executionID = empty($executionID) ? key($executions) : $executionID;
$productGroups = $this->product->getProducts($projectID);
$branchGroups = $this->project->getBranchesByProject($projectID);
$this->session->set('project', $projectID);
@@ -79,6 +81,7 @@ class build extends control
elseif($this->app->tab == 'execution')
{
$execution = $this->execution->getByID($executionID);
$executions = $this->execution->getPairs($execution->project);
$projectID = $execution->project;
$productGroups = $this->product->getProducts($executionID);
$branchGroups = $this->project->getBranchesByProject($executionID);
@@ -89,6 +92,7 @@ class build extends control
{
$execution = $this->execution->getByID($executionID);
$projectID = $execution ? $execution->project : 0;
$executions = $this->execution->getPairs($projectID);
$productGroups = $this->product->getProducts($executionID);
$branchGroups = $this->project->getBranchesByProject($executionID);
}
@@ -119,6 +123,7 @@ class build extends control
$this->view->executionID = $executionID;
$this->view->products = $products;
$this->view->projectID = $projectID;
$this->view->executions = $executions;
$this->view->lastBuild = $this->build->getLast($executionID, $projectID);
$this->view->productGroups = $productGroups;
$this->view->users = $this->user->getPairs('nodeleted|noclosed');
@@ -255,7 +260,7 @@ class build extends control
$bugPager = new pager($type == 'bug' ? $recTotal : 0, $recPerPage, $type == 'bug' ? $pageID : 1);
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('id')->in($build->bugs)
->where('id')->in($build->allBugs)
->andWhere('deleted')->eq(0)
->beginIF($type == 'bug')->orderBy($sort)->fi()
->page($bugPager)
@@ -264,7 +269,7 @@ class build extends control
/* Get stories and stages. */
$storyPager = new pager($type == 'story' ? $recTotal : 0, $recPerPage, $type == 'story' ? $pageID : 1);
$stories = $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder")->from(TABLE_STORY)
->where('id')->in($build->stories)
->where('id')->in($build->allStories)
->andWhere('deleted')->eq(0)
->beginIF($type == 'story')->orderBy($sort)->fi()
->page($storyPager)
@@ -277,10 +282,14 @@ class build extends control
if($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($build->project);
$objectType = 'project';
$objectID = $build->project;
}
elseif($this->app->tab == 'execution')
{
$this->loadModel('execution')->setMenu($build->execution);
$objectType = 'execution';
$objectID = $build->execution;
}
$executions = $this->loadModel('execution')->getPairs($this->session->project, 'all', 'empty');
@@ -297,18 +306,6 @@ class build extends control
$this->executeHooks($buildID);
if($this->app->tab == 'execution')
{
$objectType = 'execution';
$objectID = $build->execution;
}
else
{
$objectType = 'project';
$objectID = $build->project;
}
/* Assign. */
$this->view->canBeChanged = common::canBeChanged('build', $build); // Determines whether an object is editable.
$this->view->users = $this->loadModel('user')->getPairs('noletter');
@@ -611,11 +608,11 @@ class build extends control
$executionID = $build->execution ? $build->execution : $build->project;
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch($build->product, $build->branch, $queryID, 'id', $executionID, 'story', $build->stories, $pager);
$allStories = $this->story->getBySearch($build->product, $build->branch, $queryID, 'id', $executionID, 'story', $build->allStories, $pager);
}
else
{
$allStories = $this->story->getExecutionStories($executionID, $build->product, 0, 't1.`order`_desc', 'byBranch', $build->branch, 'story', $build->stories, $pager);
$allStories = $this->story->getExecutionStories($executionID, $build->product, 0, 't1.`order`_desc', 'byBranch', $build->branch, 'story', $build->allStories, $pager);
}
$this->view->allStories = $allStories;
@@ -735,11 +732,11 @@ class build extends control
$executionID = $build->execution ? $build->execution : $build->project;
if($browseType == 'bySearch')
{
$allBugs = $this->bug->getBySearch($build->product, $build->branch, $queryID, 'id_desc', $build->bugs, $pager, $build->project);
$allBugs = $this->bug->getBySearch($build->product, $build->branch, $queryID, 'id_desc', $build->allBugs, $pager, $build->project);
}
else
{
$allBugs = $this->bug->getExecutionBugs($executionID, 0, 'all', $buildID, 'noclosed', 0, 'status_desc,id_desc', $build->bugs, $pager);
$allBugs = $this->bug->getExecutionBugs($executionID, 0, 'all', $buildID, 'noclosed', 0, 'status_desc,id_desc', $build->allBugs, $pager);
}
$this->view->allBugs = $allBugs;
+50
View File
@@ -15,5 +15,55 @@ $().ready(function()
$('#builds').chosen();
});
});
$('input[name=type]').change(function()
{
if($(this).val() == 'execution')
{
$('#execution').closest('tr').show();
$('#buildBox').closest('tr').hide();
loadProducts($('#execution').val());
}
else
{
$('#execution').closest('tr').hide();
$('#buildBox').closest('tr').show();
loadProducts($('#project').val());
}
});
$('#product').change();
});
/**
* Load products.
*
* @param int $executionID
* @access public
* @return void
*/
function loadProducts(executionID)
{
$('#product').remove();
$('#product_chosen').remove();
$('#branch').remove();
$('#branch_chosen').remove();
$('#noProduct').remove();
$.get(createLink('product', 'ajaxGetProducts', 'executionID=' + executionID), function(data)
{
if(data)
{
if(data.indexOf("required") != -1)
{
$('#productBox').addClass('required');
}
else
{
$('#productBox').removeClass('required');
}
$('#productBox').append(data);
$('#product').chosen();
loadBranches($("#product").val());
}
});
}
+5
View File
@@ -33,6 +33,7 @@ $lang->build->project = 'Project';
$lang->build->branch = 'Platform/Branch';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->type = 'Type';
$lang->build->builds = 'Linked Builds';
$lang->build->name = 'Name';
$lang->build->date = 'Datum';
@@ -73,3 +74,7 @@ $lang->build->action->buildopened = '$date, erstellt von <strong>$actor</strong>
$lang->backhome = 'zurück';
$lang->build->featureBar['browse']['all'] = 'Build List';
$lang->build->typeList = array();
$lang->build->typeList['execution'] = "{$lang->executionCommon}版本";
$lang->build->typeList['project'] = '项目版本';
+5
View File
@@ -34,6 +34,7 @@ $lang->build->branch = 'Platform/Branch';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->builds = 'Linked Builds';
$lang->build->type = 'Type';
$lang->build->name = 'Name';
$lang->build->date = 'Date';
$lang->build->builder = 'Builder';
@@ -73,3 +74,7 @@ $lang->build->action->buildopened = '$date, created by <strong>$actor</strong>,
$lang->backhome = 'back';
$lang->build->featureBar['browse']['all'] = 'Build List';
$lang->build->typeList = array();
$lang->build->typeList['execution'] = "{$lang->executionCommon}版本";
$lang->build->typeList['project'] = '项目版本';
+5
View File
@@ -33,6 +33,7 @@ $lang->build->project = 'Project';
$lang->build->branch = 'Plateforme/Branche';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->type = 'Type';
$lang->build->builds = 'Linked Builds';
$lang->build->name = 'Nom';
$lang->build->date = 'Date';
@@ -73,3 +74,7 @@ $lang->build->action->buildopened = '$date, Build <strong>$extra</strong> créé
$lang->backhome = 'Retour';
$lang->build->featureBar['browse']['all'] = 'Build List';
$lang->build->typeList = array();
$lang->build->typeList['execution'] = "{$lang->executionCommon}版本";
$lang->build->typeList['project'] = '项目版本';
+5
View File
@@ -33,6 +33,7 @@ $lang->build->project = '所属项目';
$lang->build->branch = '平台/分支';
$lang->build->branchName = '所属%s';
$lang->build->execution = '所属' . $lang->executionCommon;
$lang->build->type = '版本类型';
$lang->build->builds = '关联版本';
$lang->build->name = '名称编号';
$lang->build->date = '打包日期';
@@ -71,3 +72,7 @@ $lang->build->action = new stdclass();
$lang->build->action->buildopened = '$date, 由 <strong>$actor</strong> 创建版本 <strong>$extra</strong>。' . "\n";
$lang->backhome = '返回';
$lang->build->typeList = array();
$lang->build->typeList['execution'] = "{$lang->executionCommon}版本";
$lang->build->typeList['project'] = '项目版本';
+20 -33
View File
@@ -31,6 +31,7 @@ class buildModel extends model
->fetch();
if(!$build) return false;
$build = $this->linkChildBuilds($build);
$build = $this->loadModel('file')->replaceImgURL($build, 'desc');
$build->files = $this->file->getByObject('build', $buildID);
if($setImgSize) $build->desc = $this->file->setImgSize($build->desc);
@@ -302,42 +303,31 @@ class buildModel extends model
/**
* Create a build
*
* @param int $executionID
* @param int $projectID
* @access public
* @return void
*/
public function create($executionID = 0, $projectID = 0)
public function create()
{
$build = new stdclass();
$build->stories = '';
$build->bugs = '';
if($projectID && !$executionID)
{
$project = $this->loadModel('project')->getByID($projectID);
if(!$project->multiple) $executionID = $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq($projectID)->fetch('id');
}
else if($executionID && !$projectID)
{
$execution = $this->loadModel('execution')->getByID($executionID);
$projectID = $execution->project;
}
$build = fixer::input('post')
->setDefault('project', $projectID)
->setDefault('project', 0)
->setDefault('execution', 0)
->setDefault('product', 0)
->setDefault('branch', 0)
->setDefault('builds', '')
->cleanInt('product,branch')
->add('execution', $executionID)
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
->stripTags($this->config->build->editor->create['id'], $this->config->allowedTags)
->join('builds', ',')
->remove('resolvedBy,allchecker,files,labels,uid')
->remove('resolvedBy,allchecker,files,labels,type,uid')
->get();
if($this->post->type == 'project') $build->execution = 0;
$build = $this->loadModel('file')->processImgURL($build, $this->config->build->editor->create['id'], $this->post->uid);
$this->dao->insert(TABLE_BUILD)->data($build)
->autoCheck()
@@ -349,7 +339,6 @@ class buildModel extends model
if(!dao::isError())
{
$buildID = $this->dao->lastInsertID();
$this->linkChildBuilds($buildID, $build->builds);
$this->file->updateObjectID($this->post->uid, $buildID, 'build');
$this->file->saveUpload('build', $buildID);
$this->loadModel('score')->create('build', 'create', $buildID);
@@ -389,8 +378,6 @@ class buildModel extends model
if(isset($build->branch) and $oldBuild->branch != $build->branch) $this->dao->update(TABLE_RELEASE)->set('branch')->eq($build->branch)->where('build')->eq($buildID)->exec();
if(!dao::isError())
{
$addBuilds = array_diff(explode(',', $build->builds), explode(',', $oldBuild->builds));
if($addBuilds) $this->linkChildBuilds($buildID, $addBuilds);
$this->file->updateObjectID($this->post->uid, $buildID, 'build');
return common::createChanges($oldBuild, $build);
}
@@ -569,28 +556,28 @@ class buildModel extends model
/**
* Bugs and stories associated with child builds.
*
* @param int $buildID
* @param string $childBuildIDList
* @param object $build
* @access public
* @return void
* @return object
*/
public function linkChildBuilds($buildID, $childBuildIDList)
public function linkChildBuilds($build)
{
$build = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch();
$childBuilds = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->in($childBuildIDList)->fetchAll();
$build->allBugs = $build->bugs;
$build->allStories = $build->stories;
$childBuilds = $this->dao->select('bugs, stories')->from(TABLE_BUILD)->where('id')->in($build->builds)->fetchAll();
foreach($childBuilds as $childBuild)
{
if($childBuild->bugs) $build->bugs .= ",{$childBuild->bugs}";
if($childBuild->stories) $build->stories .= ",{$childBuild->stories}";
if($childBuild->bugs) $build->allBugs .= ",{$childBuild->bugs}";
if($childBuild->stories) $build->allStories .= ",{$childBuild->stories}";
}
$build->bugs = explode(',', $build->bugs);
$build->bugs = join(',', array_unique(array_filter($build->bugs)));
$build->stories = explode(',', $build->stories);
$build->stories = join(',', array_unique(array_filter($build->stories)));
$build->allBugs = explode(',', $build->allBugs);
$build->allBugs = join(',', array_unique(array_filter($build->allBugs)));
$build->allStories = explode(',', $build->allStories);
$build->allStories = join(',', array_unique(array_filter($build->allStories)));
$this->dao->update(TABLE_BUILD)->data($build)->where('id')->eq($buildID)->exec();
return $build;
}
/**
+10 -3
View File
@@ -19,6 +19,14 @@
</div>
<form class='load-indicator main-form form-ajax' id='dataform' method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tr class="<?php echo ($app->tab == 'project' and !empty($multipleProject)) ? '' : 'hidden';?>">
<th><?php echo $lang->build->type;?></th>
<td><?php echo html::radio('type', $lang->build->typeList, 'execution');?></td>
</tr>
<tr class="<?php echo !empty($multipleProject) ? '' : 'hidden';?>">
<th><?php echo $lang->executionCommon;?></th>
<td><?php echo html::select('execution', $executions, $executionID, "onchange='loadProducts(this.value);' class='form-control chosen' required");?></td>
</tr>
<tr class="<?php echo $hidden;?>">
<th><?php echo $lang->build->product;?></th>
<?php if(!empty($products)):?>
@@ -42,13 +50,11 @@
<?php endif;?>
<td></td>
</tr>
<?php if($app->tab == 'project' && !empty($multipleProject)):?>
<tr>
<tr class='hide'>
<th><?php echo $lang->build->builds;?></th>
<td id='buildBox'><?php echo html::select('builds[]', array(), '', "class='form-control chosen' multiple");?></td>
<td><?php echo $lang->build->notice->autoRelation;?></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->build->name;?></th>
<td><?php echo html::input('name', '', "class='form-control' required");?></td>
@@ -86,6 +92,7 @@
<tr>
<td colspan="3" class="text-center form-actions">
<?php echo html::submitButton();?>
<?php echo html::hidden('project', $projectID);?>
<?php echo html::backButton();?>
</td>
</tr>
+7 -5
View File
@@ -95,10 +95,11 @@ tbody tr td:first-child input {display: none;}
</thead>
<tbody class='text-center'>
<?php foreach($stories as $storyID => $story):?>
<?php $unlinkClass = strpos(",$build->stories,", ",$story->id,") !== false ? '' : "disabled";?>
<tr>
<td class='c-id text-left'>
<?php if($canBatchUnlink):?>
<?php echo html::checkbox('unlinkStories', array($story->id => sprintf('%03d', $story->id)));?>
<?php echo html::checkbox('unlinkStories', array($story->id => sprintf('%03d', $story->id)), '', $unlinkClass);?>
<?php else:?>
<?php printf('%03d', $story->id);?>
<?php endif;?>
@@ -138,7 +139,7 @@ tbody tr td:first-child input {display: none;}
if($canBeChanged and common::hasPriv($module, 'unlinkStory'))
{
$unlinkURL = $this->createLink($module, 'unlinkStory', "buildID=$build->id&story=$story->id");
echo html::a($unlinkURL, '<i class="icon-unlink"></i>', 'hiddenwin', "class='btn' title='{$lang->build->unlinkStory}'");
echo html::a($unlinkURL, '<i class="icon-unlink"></i>', 'hiddenwin', "class='btn' title='{$lang->build->unlinkStory}' $unlinkClass");
}
?>
</td>
@@ -194,11 +195,12 @@ tbody tr td:first-child input {display: none;}
</thead>
<tbody class='text-center'>
<?php foreach($bugs as $bug):?>
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
<?php $unlinkClass = strpos(",$build->bugs,", ",$bug->id,") !== false ? '' : "disabled";?>
<tr>
<td class='c-id text-left'>
<?php if($canBatchUnlink):?>
<?php echo html::checkbox('unlinkBugs', array($bug->id => sprintf('%03d', $bug->id)));?>
<?php echo html::checkbox('unlinkBugs', array($bug->id => sprintf('%03d', $bug->id)), '', $unlinkClass);?>
<?php else:?>
<?php printf('%03d', $bug->id);?>
<?php endif;?>
@@ -219,7 +221,7 @@ tbody tr td:first-child input {display: none;}
if($canBeChanged and common::hasPriv($module, 'unlinkBug'))
{
$unlinkURL = $this->createLink($module, 'unlinkBug', "buildID=$build->id&bug=$bug->id");
echo html::a("###", '<i class="icon-unlink"></i>', '', "onclick='ajaxDelete(\"$unlinkURL\", \"bugList\", confirmUnlinkBug)' class='btn' title='{$lang->build->unlinkBug}'");
echo html::a("###", '<i class="icon-unlink"></i>', '', (!$unlinkClass ? "onclick='ajaxDelete(\"$unlinkURL\", \"bugList\", confirmUnlinkBug)'" : '') . "class='btn' title='{$lang->build->unlinkBug}' $unlinkClass");
}
?>
</td>
+3 -4
View File
@@ -145,7 +145,6 @@ class extension extends control
$this->view->upgrade = $upgrade;
$this->view->title = $installTitle . $extension;
$statusFile = $this->loadModel('common')->checkSafeFile();
if($statusFile)
{
@@ -186,7 +185,7 @@ class extension extends control
$incompatible = $condition->zentao['incompatible'];
if($this->extension->checkVersion($incompatible))
{
$this->view->error = sprintf($this->lang->extension->errorIncompatible);
$this->view->error = $this->lang->extension->errorIncompatible;
return $this->display();
}
@@ -220,7 +219,7 @@ class extension extends control
$noDepends = false;
if(isset($installedExts[$code]))
{
if($this->extension->compare4Limit($installedExts[$code]->version, $limit, 'noBetween'))$noDepends = true;
if($this->extension->compare4Limit($installedExts[$code]->version, $limit, 'noBetween')) $noDepends = true;
}
else
{
@@ -235,7 +234,7 @@ class extension extends control
if(!empty($limit['max'])) $extVersion .= ' <=v' . $limit['max'];
$extVersion .=')';
}
if($noDepends)$dependsExt .= $code . $extVersion . ' ' . html::a(inlink('obtain', 'type=bycode&param=' . helper::safe64Encode($code)), $this->lang->extension->installExt, '_blank') . '<br />';
if($noDepends) $dependsExt .= $code . $extVersion . ' ' . html::a(inlink('obtain', 'type=bycode&param=' . helper::safe64Encode($code)), $this->lang->extension->installExt, '_blank') . '<br />';
}
if($noDepends)
+6 -4
View File
@@ -525,9 +525,11 @@ class extensionModel extends model
/* Extract files. */
$packageFile = $this->getPackageFile($extension);
$this->app->loadClass('pclzip', true);
$zip = new pclzip($packageFile);
$files = $zip->listContent();
$removePath = $files[0]['filename'];
$zip = new pclzip($packageFile);
$files = $zip->listContent();
$pathinfo = pathinfo($files[0]['filename']);
$removePath = isset($pathinfo['dirname']) && $pathinfo['dirname'] != '.' ? $pathinfo['dirname'] : $pathinfo['basename'];
if($zip->extract(PCLZIP_OPT_PATH, $extensionPath, PCLZIP_OPT_REMOVE_PATH, $removePath) == 0)
{
$return->result = 'fail';
@@ -548,7 +550,7 @@ class extensionModel extends model
{
$appRoot = $this->app->getAppRoot();
$extensionDir = "ext/$extension/";
$paths = scandir($extensionDir);
$paths = scandir($extensionDir);
$copiedFiles = array();
foreach($paths as $path)
+1 -1
View File
@@ -3,7 +3,7 @@ $maxUploadSize = strtoupper(ini_get('upload_max_filesize'));
js::set('dangerExtensions', ',' . $this->config->file->dangers . ',');
js::set('maxUploadSize', $maxUploadSize);
?>
<div class="file-input-list" data-append-way="before" data-provide="fileInputList" data-each-file-max-size="<?php echo $maxUploadSize; ?>" data-file-size-error="<?php echo sprintf($lang->file->errorFileSize, $maxUploadSize); ?>">
<div class="file-input-list" data-append-way="before" data-filedName="<?php echo $filesName;?>" data-provide="fileInputList" data-each-file-max-size="<?php echo $maxUploadSize; ?>" data-file-size-error="<?php echo sprintf($lang->file->errorFileSize, $maxUploadSize); ?>">
<div class="file-input">
<div class="file-input-edit input-group">
<div class="input-group-cell"><i class="icon icon-paper-clip text-muted"></i></div>
-2
View File
@@ -237,7 +237,6 @@ $lang->project->methodOrder[190] = 'manageRepo';
$lang->resource->projectbuild = new stdclass();
$lang->resource->projectbuild->browse = 'browse';
$lang->resource->projectbuild->create = 'create';
$lang->resource->projectbuild->edit = 'edit';
$lang->resource->projectbuild->view = 'view';
$lang->resource->projectbuild->delete = 'delete';
@@ -249,7 +248,6 @@ $lang->resource->projectbuild->unlinkBug = 'unlinkBug';
$lang->resource->projectbuild->batchUnlinkBug = 'batchUnlinkBug';
$lang->projectbuild->methodOrder[5] = 'browse';
$lang->projectbuild->methodOrder[10] = 'create';
$lang->projectbuild->methodOrder[15] = 'edit';
$lang->projectbuild->methodOrder[20] = 'view';
$lang->projectbuild->methodOrder[25] = 'delete';
+2 -1
View File
@@ -198,12 +198,13 @@ class holidayModel extends model
{
if(empty($begin) or empty($end) or $begin == '0000-00-00' or $end == '0000-00-00') return array();
$this->app->loadConfig('execution');
$actualDays = array();
$currentDay = $begin;
$holidays = $this->getHolidays($begin, $end);
$workingDays = $this->getWorkingDays($begin, $end);
$weekend = isset($this->config->project->weekend) ? $this->config->project->weekend : 2;
$weekend = isset($this->config->execution->weekend) ? $this->config->execution->weekend : 2;
$holidaysFlip = array_flip($holidays);
$workingDaysFlip = array_flip($workingDays);
+2 -2
View File
@@ -564,7 +564,7 @@
/* The magic number "111" is the space between dropdown trigger
btn and the bottom of screen */
var listStyle = {maxHeight: 'initial', top: moreMenuHeight > 111 ? 111 - moreMenuHeight : ''};
if($list[0].getBoundingClientRect)
if($list[0] && $list[0].getBoundingClientRect)
{
var btnBounding = $list.prev('a')[0].getBoundingClientRect();
if(btnBounding.height)
@@ -803,7 +803,7 @@ $(function()
{
var val = $searchQuery.val();
var searchType = changeSearchObject();
if(val !== null && val !== "")
if(val)
{
var isQuickGo = !reg.test(val);
$dropmenu.toggleClass('show-quick-go', isQuickGo);
+1 -1
View File
@@ -59,7 +59,7 @@ $lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/def
$lang->misc->mobile = "Mobiler Zugriff";
$lang->misc->noGDLib = "Bitte benutzen Sie den Browser Ihres Telefons um die Seite <strong>%s</strong> aufzurufen";
$lang->misc->copyright = "&copy; 2009 - 2018 <a href='http://easysoft.ltd' target='_blank'>Nature Easy Soft Network Technology Co,LTD</a> Email <a href='mailto:Max@easysoft.ltd'>Max@easysoft.ltd</a>";
$lang->misc->copyright = "&copy; 2009 - " . date('Y') . " <a href='https://easysoft.ltd' target='_blank'>Nature Easy Soft Network Technology Co,LTD</a> Email <a href='mailto:Max@easysoft.ltd'>Max@easysoft.ltd</a>";
$lang->misc->checkTable = "Prüfe Datentabellen";
$lang->misc->needRepair = "Repariere Datentabellen";
$lang->misc->repairTable = "Datenbank íst beschädigt. Bitte brüfen und reparieren!";
+1 -1
View File
@@ -59,7 +59,7 @@ $lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/def
$lang->misc->mobile = "Mobile Access";
$lang->misc->noGDLib = "Please visit <strong>%s</strong> in the browser of your phone.";
$lang->misc->copyright = "&copy; 2009 - 2019 <a href='https://easycorp.ltd/' target='_blank'>EasyCorp</a> Email <a href='mailto:Renee@easycorp.ltd'>Renee@easycorp.ltd</a>";
$lang->misc->copyright = "&copy; 2009 - " . date('Y') . " <a href='https://easycorp.ltd/' target='_blank'>EasyCorp</a> Email <a href='mailto:Renee@easycorp.ltd'>Renee@easycorp.ltd</a>";
$lang->misc->checkTable = "Check Data Table";
$lang->misc->needRepair = "Repair Table";
$lang->misc->repairTable = "Database table might be damaged due to power outage. Please check and repair!";
+1 -1
View File
@@ -59,7 +59,7 @@ $lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/def
$lang->misc->mobile = "Accès Mobile";
$lang->misc->noGDLib = "SVP visitez <strong>%s</strong> via le navigateur de votre smartphone.";
$lang->misc->copyright = "&copy; 2009 - 2019 <a href='http://easysoft.ltd' target='_blank'>Nature Easy Soft</a> Email <a href='mailto:Renee@easysoft.ltd'>Renee@easysoft.ltd</a>";
$lang->misc->copyright = "&copy; 2009 - " . date('Y') . " <a href='https://easysoft.ltd' target='_blank'>Nature Easy Soft</a> Email <a href='mailto:Renee@easysoft.ltd'>Renee@easysoft.ltd</a>";
$lang->misc->checkTable = "Vérifiez les Données de la Table";
$lang->misc->needRepair = "Réparer la Table";
$lang->misc->repairTable = "La Base de Données est peut-être endommagée. Elle a besoin d'être vérifiée et éventuellement réparée !";
+1 -1
View File
@@ -59,7 +59,7 @@ $lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/def
$lang->misc->mobile = "Mobile Access";
$lang->misc->noGDLib = "Please visit <strong>%s</strong> in the browser of your phone.";
$lang->misc->copyright = "&copy; 2009 - 2019 <a href='http://easysoft.ltd' target='_blank'>Nature Easy Soft</a> Email <a href='mailto:Renee@easysoft.ltd'>Renee@easysoft.ltd</a>";
$lang->misc->copyright = "&copy; 2009 - " . date('Y') . " <a href='https://easysoft.ltd' target='_blank'>Nature Easy Soft</a> Email <a href='mailto:Renee@easysoft.ltd'>Renee@easysoft.ltd</a>";
$lang->misc->checkTable = "Check Data Table";
$lang->misc->needRepair = "Repair Table";
$lang->misc->repairTable = "Database table might be damaged due to power outage. Vui lòng check and repair!";
+1 -1
View File
@@ -59,7 +59,7 @@ $lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/def
$lang->misc->mobile = "手机访问";
$lang->misc->noGDLib = "请用手机浏览器访问:<strong>%s</strong>";
$lang->misc->copyright = "&copy; 2009 - 2018 <a href='http://www.cnezsoft.com' target='_blank'>青岛易软天创网络科技有限公司</a> 电话:4006-8899-23 Email:<a href='mailto:co@zentao.net'>co@zentao.net</a> QQ:1492153927";
$lang->misc->copyright = "&copy; 2009 - " . date('Y') . " <a href='https://www.easycorp.cn' target='_blank'>青岛易软天创网络科技有限公司</a> 电话:4006-8899-23 Email:<a href='mailto:co@zentao.net'>co@zentao.net</a> QQ:1492153927";
$lang->misc->checkTable = "检查修复数据表";
$lang->misc->needRepair = "修复表";
$lang->misc->repairTable = "数据库表可能因为断电原因损坏,需要检查修复!!";
+1 -1
View File
@@ -59,7 +59,7 @@ $lang->misc->zentao->others['meshiot' ] = "<img src='{$config->webRoot}theme/def
$lang->misc->mobile = "手機訪問";
$lang->misc->noGDLib = "請用手機瀏覽器訪問:<strong>%s</strong>";
$lang->misc->copyright = "&copy; 2009 - 2018 <a href='http://www.cnezsoft.com' target='_blank'>青島易軟天創網絡科技有限公司</a> 電話:4006-8899-23 Email:<a href='mailto:co@zentao.net'>co@zentao.net</a> QQ:1492153927";
$lang->misc->copyright = "&copy; 2009 - " . date('Y') . " <a href='https://www.easycorp.cn' target='_blank'>青島易軟天創網絡科技有限公司</a> 電話:4006-8899-23 Email:<a href='mailto:co@zentao.net'>co@zentao.net</a> QQ:1492153927";
$lang->misc->checkTable = "檢查修復數據表";
$lang->misc->needRepair = "修復表";
$lang->misc->repairTable = "資料庫表可能因為斷電原因損壞,需要檢查修復!!";
+21
View File
@@ -880,6 +880,27 @@ class product extends control
$this->display();
}
/**
* Ajax get products.
*
* @param int $executionID
* @access public
* @return void
*/
public function ajaxGetProducts($executionID)
{
$this->loadModel('build');
$products = $this->product->getProductPairsByProject($executionID);
if(empty($products))
{
return printf($this->lang->build->noProduct, $this->createLink('execution', 'manageproducts', "executionID=$executionID&from=buildCreate", '', 'true'), 'project');
}
else
{
return print(html::select('product', $products, empty($product) ? '' : $product->id, "onchange='loadBranches(this.value);' class='form-control chosen' required data-toggle='modal' data-type='iframe'"));
}
}
/**
* AJAX: get projects of a product in html select.
*
+2 -2
View File
@@ -124,7 +124,7 @@ class productModel extends model
if($isQaModule) $moduleName = 'bug';
if($isFeedbackModel) $moduleName = 'feedback';
$dropMenuLink = helper::createLink($moduleName, 'ajaxGetDropMenu', "objectID=$productID&module=$currentModule&method=$currentMethod&extra=$extra");
$output = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem' title='{$currentProduct->name}'><span class='text'>{$currentProduct->name}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem' title='{$currentProduct->name}' style='width: 90%'><span class='text'>{$currentProduct->name}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div>";
if($isMobile) $output = "<a id='currentItem' href=\"javascript:showSearchMenu('product', '$productID', '$currentModule', '$currentMethod', '$extra')\"><span class='text'>{$currentProduct->name}</span> <span class='icon-caret-down'></span></a><div id='currentItemDropMenu' class='hidden affix enter-from-bottom layer'></div>";
@@ -140,7 +140,7 @@ class productModel extends model
if(!$isMobile)
{
$dropMenuLink = helper::createLink('branch', 'ajaxGetDropMenu', "objectID=$productID&branch=$branch&module=$currentModule&method=$currentMethod&extra=$extra");
$output .= "<div class='btn-group'><button id='currentBranch' data-toggle='dropdown' type='button' class='btn btn-limit'>{$branchName} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= "<div class='btn-group'><button id='currentBranch' data-toggle='dropdown' type='button' class='btn btn-limit' title='{$branchName}' style='width: 90%'>{$branchName} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div>";
}
+1 -1
View File
@@ -15,7 +15,7 @@
<div id='mainContent' class="main-row">
<div class="col-12 main-col">
<div class="row">
<?php $isRoadmap = common::hasPriv('product', 'roadmap');?>
<?php $isRoadmap = (common::hasPriv('product', 'roadmap') and helper::hasFeature('product_roadmap'));?>
<?php if($isRoadmap):?>
<div class="col-sm-6">
<div class="panel block-release">
+12 -9
View File
@@ -531,22 +531,21 @@ class productplanModel extends model
->get();
$parentPlan = $this->getByID($plan->parent);
$futureTime = $this->config->productplan->future;
if($plan->parent > 0)
{
if($parentPlan->begin !== $this->config->productplan->future)
if($parentPlan->begin !== $futureTime)
{
if($plan->begin < $parentPlan->begin) dao::$errors['begin'] = sprintf($this->lang->productplan->beginLetterParent, $parentPlan->begin);
}
if($parentPlan->end !== $this->config->productplan->future)
if($parentPlan->end !== $futureTime)
{
if($plan->end !== $this->config->productplan->future and $plan->end > $parentPlan->end) dao::$errors['end'] = sprintf($this->lang->productplan->endGreaterParent, $parentPlan->end);
if($plan->end !== $futureTime and $plan->end > $parentPlan->end) dao::$errors['end'] = sprintf($this->lang->productplan->endGreaterParent, $parentPlan->end);
}
}
elseif($oldPlan->parent == -1 and $plan->begin != $this->config->productplan->future)
elseif($oldPlan->parent == -1 and ($plan->begin != $futureTime or $plan->end != $futureTime))
{
$plan->parent = -1;
$childPlans = $this->getChildren($planID);
$minBegin = $plan->begin;
$maxEnd = $plan->end;
@@ -556,8 +555,8 @@ class productplanModel extends model
if($childPlan->begin < $minBegin) $minBegin = $childPlan->begin;
if($childPlan->end > $maxEnd) $maxEnd = $childPlan->end;
}
if($minBegin < $plan->begin and $minBegin != $this->config->productplan->future) dao::$errors['begin'] = sprintf($this->lang->productplan->beginGreaterChildTip, $oldPlan->title, $plan->begin, $minBegin);
if($maxEnd > $plan->end and $maxEnd != $this->config->productplan->future) dao::$errors['end'] = sprintf($this->lang->productplan->endLetterChildTip, $oldPlan->title, $plan->end, $maxEnd);
if($minBegin < $plan->begin and $minBegin != $futureTime) dao::$errors['begin'] = sprintf($this->lang->productplan->beginGreaterChildTip, $oldPlan->title, $plan->begin, $minBegin);
if($maxEnd > $plan->end and $maxEnd != $futureTime) dao::$errors['end'] = sprintf($this->lang->productplan->endLetterChildTip, $oldPlan->title, $plan->end, $maxEnd);
}
if(dao::isError()) return false;
@@ -647,7 +646,11 @@ class productplanModel extends model
$childStatus = $this->dao->select('status')->from(TABLE_PRODUCTPLAN)->where('parent')->eq($parentID)->andWhere('deleted')->eq(0)->fetchPairs();
/* If the subplan is empty, update the plan. */
if(empty($childStatus)) $this->dao->update(TABLE_PRODUCTPLAN)->set('parent')->eq(0)->where('id')->eq($parentID)->exec();
if(empty($childStatus))
{
$this->dao->update(TABLE_PRODUCTPLAN)->set('parent')->eq(0)->set('status')->eq('wait')->where('id')->eq($parentID)->exec();
return;
}
if(count($childStatus) == 1 and isset($childStatus['wait']))
{
+5 -1
View File
@@ -41,10 +41,14 @@
<th><?php echo $lang->productplan->title;?></th>
<td><?php echo html::input('title', $plan->title, "class='form-control' required");?></td><td></td><td></td>
</tr>
<tr <?php echo $plan->parent == '-1' ? "class='hidden'": '';?>>
<?php if($plan->parent == '-1'):?>
<?php echo html::hidden('parent', $plan->parent);?>
<?php else:?>
<tr>
<th><?php echo $lang->productplan->parent;?></th>
<td><?php echo html::select('parent', array('0' => '') + $parentPlanPairs, $plan->parent, "class='form-control chosen'");?>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->productplan->status;?></th>
<?php $disabled = $plan->parent == -1 ? "disabled='disabled'" : '' ;?>
+1 -1
View File
@@ -102,7 +102,7 @@ $lang->programplan->ganttCustom['delay'] = '是否延期';
$lang->programplan->ganttCustom['delayDays'] = '延期天数';
$lang->programplan->error = new stdclass();
$lang->programplan->error->percentNumber = '"工作量比例"必须为数字';
$lang->programplan->error->percentNumber = '"工作量占比"必须为数字';
$lang->programplan->error->planFinishSmall = '"计划完成时间"必须大于"计划开始时间"';
$lang->programplan->error->percentOver = '工作量占比累计不应当超过100%';
$lang->programplan->error->createdTask = '已分解任务,不可添加子阶段';
+1 -1
View File
@@ -72,7 +72,7 @@ $lang->programplan->stageCustom->date = '顯示日期';
$lang->programplan->stageCustom->task = '顯示任務';
$lang->programplan->error = new stdclass();
$lang->programplan->error->percentNumber = '"工作量比例"必須為數字';
$lang->programplan->error->percentNumber = '"工作量占比"必須為數字';
$lang->programplan->error->planFinishSmall = '"計劃完成時間"必須大於"計劃開始時間"';
$lang->programplan->error->percentOver = '工作量占比累計不應當超過100%';
$lang->programplan->error->createdTask = '已分解任務,不可添加子階段';
+17 -1
View File
@@ -1,6 +1,22 @@
<?php
class projectModel extends model
{
/**
* Check the privilege.
*
* @param int $projectID
* @access public
* @return bool
*/
public function checkPriv($projectID)
{
if(empty($projectID)) return false;
/* If is admin, return true. */
if($this->app->user->admin) return true;
return (strpos(",{$this->app->user->view->projects},", ",{$projectID},") !== false);
}
/**
* Get Multiple linked products for project.
*
@@ -3003,7 +3019,7 @@ class projectModel extends model
$menu .= "<div class='btn-group'>";
$menu .= "<button type='button' class='btn dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}'><i class='icon-ellipsis-v'></i></button>";
$menu .= "<ul class='dropdown-menu pull-right text-center' role='menu'>";
$menu .= $this->buildMenu($moduleName, 'manageProducts', $params . "&from={$this->app->tab}", $project, 'browse', 'link', '', 'btn-action', '', '', $this->lang->project->manageProducts);
if($project->hasProduct) $menu .= $this->buildMenu($moduleName, 'manageProducts', $params . "&from={$this->app->tab}", $project, 'browse', 'link', '', 'btn-action', '', '', $this->lang->project->manageProducts);
$menu .= $this->buildMenu('project', 'whitelist', "$params&module=project&from=$from", $project, 'browse', 'shield-check', '', 'btn-action', '', $dataApp);
$menu .= $this->buildMenu($moduleName, "delete", $params, $project, 'browse', 'trash', 'hiddenwin', 'btn-action');
$menu .= "</ul>";
+1 -1
View File
@@ -24,7 +24,7 @@
#swapper li {padding-top: 0; padding-bottom: 0;}
#swapper .tree li>.list-toggle {top: -1px;}
div#closed {width: 90px; height: 25px; line-height: 25px; background-color: #ddd; color: #3c495c; text-align: center; margin-left: 15px; border-radius: 2px;}
#dropMenu div#closed {width: 90px; height: 25px; line-height: 25px; background-color: #ddd; color: #3c495c; text-align: center; margin-left: 15px; border-radius: 2px;}
#gray-line {width:230px; height: 1px; margin-left: 10px; margin-bottom:2px; background-color: #ddd;}
</style>
<?php
+1 -1
View File
@@ -35,7 +35,7 @@
<a class="btn btn-link querybox-toggle" id="bysearchTab"><i class="icon icon-search muted"></i> <?php echo $lang->execution->byQuery;?></a>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::canModify('project', $project)) common::printLink('projectbuild', 'create', "projectID=$projectID", "<i class='icon icon-plus'></i> " . $lang->build->create, '', "class='btn btn-primary' id='createBuild'");?>
<?php if(common::canModify('project', $project)) common::printLink('build', 'create', "executionID=&productID=&projectID=$projectID", "<i class='icon icon-plus'></i> " . $lang->build->create, '', "class='btn btn-primary' id='createBuild'");?>
</div>
</div>
<div id="mainContent">
+1 -1
View File
@@ -66,7 +66,7 @@ class releaseModel extends model
->page($pager)
->fetchAll();
$builds = $this->dao->select("t1.id, t1.name, t1.execution, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName")
$builds = $this->dao->select("t1.id, t1.name, t1.project, t1.execution, IF(t2.name IS NOT NULL, t2.name, '') AS projectName, IF(t3.name IS NOT NULL, t3.name, '{$this->lang->trunk}') AS branchName")
->from(TABLE_BUILD)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->leftJoin(TABLE_BRANCH)->alias('t3')->on('t1.branch = t3.id')
+11 -1
View File
@@ -63,6 +63,10 @@
</tr>
</thead>
<tbody>
<?php
$this->loadModel('project');
$this->loadModel('execution');
?>
<?php foreach($releases as $release):?>
<?php $canBeChanged = common::canBeChanged('release', $release);?>
<?php $buildCount = count($release->builds);?>
@@ -82,7 +86,13 @@
<?php if($product->type != 'normal'):?>
<span class='label label-outline label-badge'><?php echo $build->branchName;?></span>
<?php endif;?>
<?php echo html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name);?>
<?php
$moduleName = $build->execution ? 'build' : 'projectbuild';
$canClickable = false;
if($moduleName == 'projectbuild' and $this->project->checkPriv($build->project)) $canClickable = true;
if($moduleName == 'build' and $this->execution->checkPriv($build->execution)) $canClickable = true;
echo $canClickable ? html::a($this->createLink($moduleName, 'view', "buildID=$build->id"), $build->name, '', "data-app='project'") : $build->name;
?>
</td>
<td><?php echo $build->projectName;?></td>
<?php if($i == 1):?>
+6 -1
View File
@@ -356,7 +356,12 @@
$buildHtml = array();
foreach($release->builds as $build)
{
$buildHtml[] = html::a($this->createLink($build->execution ? 'build' : 'projectbuild', 'view', "buildID=$build->id"), $build->name, '', "data-app='project'");
$moduleName = $build->execution ? 'build' : 'projectbuild';
$canClickable = false;
if($moduleName == 'projectbuild' and $this->loadModel('project')->checkPriv($build->project)) $canClickable = true;
if($moduleName == 'build' and $this->loadModel('execution')->checkPriv($build->execution)) $canClickable = true;
$buildHtml[] = $canClickable ? html::a($this->createLink($moduleName, 'view', "buildID=$build->id"), $build->name, '', "data-app='project'") : $build->name;
}
echo join($lang->comma, $buildHtml);
?>
+2 -1
View File
@@ -1,6 +1,6 @@
$(function()
{
scmChanged(scm, true);
scmChanged(repoSCM, true);
$('#submit').mousedown(function()
{
$form = $(this).closest('form');
@@ -86,6 +86,7 @@ function scmChanged(scm, isFirstRequest = false)
if(scm == 'Git' || scm == 'Gitea' || scm == 'Gogs')
{
$('.account-fields').addClass('hidden');
if(['Git', 'Gitea', 'Gogs'].indexOf(repoSCM) === -1) $('#client').val('');
$('.tips-git').removeClass('hidden');
$('.tips-svn').addClass('hidden');
+1
View File
@@ -253,6 +253,7 @@ class repoModel extends model
public function update($id)
{
$repo = $this->getRepoByID($id);
if(!$this->checkConnection()) return false;
$isPipelineServer = in_array(strtolower($this->post->SCM), $this->config->repo->gitServiceList) ? true : false;
+1 -1
View File
@@ -18,7 +18,7 @@
.user-addon{padding-right: 16px; padding-left: 16px;}
</style>
<?php endif;?>
<?php js::set('scm', $repo->SCM);?>
<?php js::set('repoSCM', $repo->SCM);?>
<?php js::set('objectID', $objectID);?>
<div id='mainContent' class='main-row'>
<div class='main-col main-content'>
+4
View File
@@ -726,6 +726,7 @@ class reportModel extends model
->orWhere('RD')->in($accounts)
->markRight(1)
->fi()
->andWhere('shadow')->eq(0)
->fetchAll('id');
/* Get created plans in this year. */
@@ -733,6 +734,7 @@ class reportModel extends model
->leftJoin(TABLE_ACTION)->alias('t2')->on("t1.id=t2.objectID and t2.objectType='productplan'")
->where('LEFT(t2.date, 4)')->eq($year)
->andWhere('t1.deleted')->eq(0)
->andWhere('t1.product')->in(array_keys($products))
->beginIF($accounts)
->andWhere('t2.actor')->in($accounts)
->fi()
@@ -750,11 +752,13 @@ class reportModel extends model
$createStoryProducts = $this->dao->select('DISTINCT product')->from(TABLE_STORY)
->where('LEFT(openedDate, 4)')->eq($year)
->andWhere('deleted')->eq(0)
->andWhere('product')->in(array_keys($products))
->beginIF($accounts)->andWhere('openedBy')->in($accounts)->fi()
->fetchPairs('product', 'product');
$closeStoryProducts = $this->dao->select('DISTINCT product')->from(TABLE_STORY)
->where('LEFT(closedDate, 4)')->eq($year)
->andWhere('deleted')->eq(0)
->andWhere('product')->in(array_keys($products))
->beginIF($accounts)->andWhere('closedBy')->in($accounts)->fi()
->fetchPairs('product', 'product');
if($createStoryProducts or $closeStoryProducts)
+4 -3
View File
@@ -2714,7 +2714,7 @@ class story extends control
$this->story->replaceURLang($storyType);
$this->products = $this->product->getPairs('', 0, '', 'all');
if($this->app->tab == 'project')
if(strpos('project,execution', $this->app->tab) !== false)
{
$project = $this->dao->findByID($projectID)->from(TABLE_PROJECT)->fetch();
if($project->type == 'project')
@@ -2727,10 +2727,11 @@ class story extends control
$this->loadModel('execution')->setMenu($projectID);
}
if(!$project->hasProduct and !$project->multiple)
if(!$project->hasProduct)
{
unset($this->lang->story->report->charts['storysPerProduct']);
unset($this->lang->story->report->charts['storysPerPlan']);
if(!$project->multiple) unset($this->lang->story->report->charts['storysPerPlan']);
}
}
else
+1 -1
View File
@@ -1,5 +1,5 @@
.c-id {width: 50px;}
.c-reason {width: 150px;}
.c-reason {width: 210px;}
td[id^="duplicateStoryBox"].required:after {top: 6px; right: 2px;}
td[id^="duplicateStoryBox"] {overflow: visible;}
td.reasons-td {overflow: visible;}
-6
View File
@@ -12,22 +12,16 @@ function setDuplicateAndChild(resolution, storyID)
{
$('#childStoryBox' + storyID).hide();
$('#duplicateStoryBox' + storyID).show();
$('#duplicateStoryTitle').show();
$('.form-actions').attr('colspan', 6);
}
else if(resolution == 'subdivided')
{
$('#duplicateStoryBox' + storyID).hide();
$('#childStoryBox' + storyID).show();
$('#duplicateStoryTitle').hide();
$('.form-actions').attr('colspan', 5);
}
else
{
$('#duplicateStoryBox' + storyID).hide();
$('#childStoryBox' + storyID).hide();
$('#duplicateStoryTitle').hide();
$('.form-actions').attr('colspan', 5);
}
}
+3
View File
@@ -4944,6 +4944,9 @@ class storyModel extends model
case 'assignedDate':
echo helper::isZeroDate($story->assignedDate) ? '' : substr($story->assignedDate, 5, 11);
break;
case 'activatedDate':
echo helper::isZeroDate($story->activatedDate) ? '' : substr($story->activatedDate, 5, 11);
break;
case 'reviewedBy':
echo $story->reviewedBy;
break;
+3 -4
View File
@@ -28,7 +28,6 @@
<th class='text-left'><?php echo $lang->story->title;?></th>
<th class='c-status'><?php echo $lang->story->status;?></th>
<th class='c-reason'><?php echo $lang->story->closedReason;?></th>
<th id='duplicateStoryTitle' class='w-p15' style='display:none;'><?php echo $lang->story->duplicateStory;?></th>
<th class='w-p30'><?php echo $lang->story->comment;?></th>
</tr>
</thead>
@@ -44,15 +43,15 @@
<td class='pd-0'>
<?php echo html::select("closedReasons[$storyID]", $reasonList, 'done', "class=form-control onchange=setDuplicateAndChild(this.value,$storyID) style='min-width: 80px'");?>
</td>
<td class='pd-0 w-p60 text-left' id='<?php echo 'duplicateStoryBox' . $storyID;?>' <?php if($story->closedReason != 'duplicate') echo "style='display:none'";?>>
<?php echo html::select("duplicateStoryIDList[$storyID]", array('' => '') + $productStoryList[$story->product][$story->branch], $story->duplicateStory ? $story->duplicateStory : '', "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?>
</td>
<td class='pd-0' id='<?php echo 'childStoryBox' . $storyID;?>' <?php if($story->closedReason != 'subdivided') echo "style='display:none'";?>>
<?php echo html::input("childStoriesIDList[$storyID]", '', "class='form-control' placeholder='{$lang->idAB}'");?>
</td>
</tr>
</table>
</td>
<td class='text-left' id='<?php echo 'duplicateStoryBox' . $storyID;?>' <?php if($story->closedReason != 'duplicate') echo "style='display:none'";?>>
<?php echo html::select("duplicateStoryIDList[$storyID]", array('' => '') + $productStoryList[$story->product][$story->branch], $story->duplicateStory ? $story->duplicateStory : '', "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?>
</td>
<td><?php echo html::input("comments[$storyID]", '', "class='form-control'");?></td>
</tr>
<?php endforeach;?>
+3 -3
View File
@@ -415,7 +415,7 @@
<div class="cell">
<div class='tabs'>
<ul class='nav nav-tabs'>
<?php if($this->config->URAndSR && !$hiddenURS):?>
<?php if($this->config->URAndSR and !$hiddenURS):?>
<li class='active'><a href='#legendStories' data-toggle='tab'><?php echo $story->type == 'story' ? $lang->story->requirement : $lang->story->story;?></a></li>
<?php endif;?>
<?php if($story->type == 'story'):?>
@@ -424,7 +424,7 @@
<li><a href='#legendRelated' data-toggle='tab'><?php echo $lang->story->legendRelated;?></a></li>
</ul>
<div class='tab-content'>
<?php if($this->config->URAndSR && !$hiddenURS):?>
<?php if($this->config->URAndSR and !$hiddenURS):?>
<div class='tab-pane active' id='legendStories'>
<ul class="list-unstyled">
<?php
@@ -571,7 +571,7 @@
</ul>
</td>
</tr>
<?php if($story->type == 'story'):?>
<?php if($story->type == 'story' and helper::hasFeature('devops')):?>
<tr>
<th><?php echo $lang->story->linkMR;?></th>
<td class='pd-0'>
-1
View File
@@ -322,7 +322,6 @@ class testcase extends control
{
$this->loadModel('project')->setMenu($this->session->project);
$this->app->rawModule = 'qa';
$this->lang->project->menu->qa['subMenu']->testcase['subModule'] = 'story';
$products = $this->product->getProducts($this->session->project, 'all', '', false);
$productID = $this->product->saveState($productID, $products);
$this->lang->modulePageNav = $this->product->select($products, $productID, 'testcase', 'zeroCase', "projectID=$projectID", $branchID);
+1 -2
View File
@@ -9,8 +9,7 @@
#mainContent tr th {background-color: rgb(241, 241, 241);}
#mainContent tr td {background-color: rgb(255, 255, 255); border-bottom: 1px solid rgb(238, 238, 238); border-right: 1px solid rgb(238, 238, 238);}
#useLight {background-color: #ddd!important; padding: 6px 85px;}
#useALM {background-color: #ddd!important; padding: 6px 85px;}
#useLight, #useALM {border: #93969b 1px solid; padding: 6px 85px;}
#mainContent .datatable {cursor: default;}
.container {padding-top: 20px;}