Merge branch 'master' of github.com:easysoft/zentaopms

This commit is contained in:
z
2020-08-06 15:32:27 +08:00
27 changed files with 138 additions and 72 deletions
+3 -2
View File
@@ -16,6 +16,7 @@
<style>
.block-tasks .c-id {width: 55px;}
.block-tasks .c-pri {width: 45px;text-align: center;}
.block-tasks .c-pri-long {width: 80px;}
.block-tasks .c-estimate {width: 60px;}
.block-tasks .c-deadline {width: 95px;}
.block-tasks .c-status {width: 80px;}
@@ -26,7 +27,7 @@
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-pri'><?php echo $lang->priAB?></th>
<th class='c-pri <?php if($longBlock) echo "c-pri-long"?>'><?php echo $lang->priAB?></th>
<th class='c-name'> <?php echo $lang->task->name;?></th>
<?php if($longBlock):?>
<th class='c-estimate'><?php echo $lang->task->estimateAB;?></th>
@@ -43,7 +44,7 @@
?>
<tr data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
<td class='c-id-xs'><?php echo sprintf('%03d', $task->id);?></td>
<td class='c-pri'><span class='label-pri label-pri-<?php echo $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri, $task->pri)?>'><?php echo zget($lang->task->priList, $task->pri, $task->pri)?></span></td>
<td class='c-pri <?php if($longBlock) echo "c-pri-long"?>'><span class='label-pri label-pri-<?php echo $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri, $task->pri)?>'><?php echo zget($lang->task->priList, $task->pri, $task->pri)?></span></td>
<td class='c-name' style='color: <?php echo $task->color?>' title='<?php echo $task->name?>'><?php echo $task->name?></td>
<?php if($longBlock):?>
<td class='c-estimate text-center'><?php echo $task->estimate?></td>
+4 -1
View File
@@ -539,18 +539,21 @@ class bugModel extends model
* @param array $products
* @param int $branch
* @param int $projectID
* @param array $excludeBugs
* @param object $pager
* @access public
* @return array
*/
public function getActiveBugs($products, $branch, $projects, $pager = null)
public function getActiveBugs($products, $branch, $projects, $excludeBugs, $pager = null)
{
return $this->dao->select('*')->from(TABLE_BUG)
->where('status')->eq('active')
->andWhere('tostory')->eq(0)
->andWhere('toTask')->eq(0)
->beginIF(!empty($products))->andWhere('product')->in($products)->fi()
->beginIF($branch)->andWhere('branch')->in("0,$branch")->fi()
->beginIF(!empty($projects))->andWhere('project')->in($projects)->fi()
->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi()
->andWhere('deleted')->eq(0)
->orderBy('id desc')
->page($pager)
+1 -1
View File
@@ -479,7 +479,7 @@ class build extends control
}
else
{
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byModule', 0, 'story', $build->stories, $pager);
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byProduct', $build->product, 'story', $build->stories, $pager);
}
$this->view->allStories = $allStories;
-2
View File
@@ -37,8 +37,6 @@
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allBugs as $bug):?>
<?php if(strpos(",{$build->bugs},", ",$bug->id,") !== false) continue;?>
<?php if($build->product != $bug->product) continue; ?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('bugs', array($bug->id => sprintf('%03d', $bug->id)), ($bug->status == 'resolved' or $bug->status == 'closed') ? $bug->id : '');?>
-2
View File
@@ -39,8 +39,6 @@
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allStories as $story):?>
<?php if(strpos(",{$build->stories},", ",{$story->id},") !== false) continue; ?>
<?php if($build->product != $story->product) continue; ?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('stories', array($story->id => sprintf('%03d', $story->id)), ($story->stage == 'developed' or $story->status == 'closed') ? $story->id : '');?>
+3 -3
View File
@@ -571,11 +571,11 @@ class productModel extends model
{
$unclosedStatus = $this->lang->story->statusList;
unset($unclosedStatus['closed']);
$stories = $this->story->getProductStories($productID, $branch, $modules, array_keys($unclosedStatus), $type, $sort, $pager);
$stories = $this->story->getProductStories($productID, $branch, $modules, array_keys($unclosedStatus), $type, $sort, true, '', $pager);
}
if($browseType == 'unplan') $stories = $this->story->getByPlan($productID, $queryID, $modules, '', $type, $sort, $pager);
if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, $pager);
if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, $pager);
if($browseType == 'allstory') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, true, '', $pager);
if($browseType == 'bymodule') $stories = $this->story->getProductStories($productID, $branch, $modules, 'all', $type, $sort, true, '', $pager);
if($browseType == 'bysearch') $stories = $this->story->getBySearch($productID, $branch, $queryID, $sort, '', $type, '', $pager);
if($browseType == 'assignedtome') $stories = $this->story->getByAssignedTo($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager);
if($browseType == 'openedbyme') $stories = $this->story->getByOpenedBy($productID, $branch, $modules, $this->app->user->account, $type, $sort, $pager);
+42 -19
View File
@@ -234,11 +234,14 @@ class productplan extends control
* @param string $orderBy
* @param string $link
* @param string $param
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
*
* @access public
* @return void
*/
public function view($planID = 0, $type = 'story', $orderBy = 'id_desc', $link = 'false', $param = '')
public function view($planID = 0, $type = 'story', $orderBy = 'id_desc', $link = 'false', $param = '', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
$plan = $this->productplan->getByID($planID, true);
if(!$plan) die(js::error($this->lang->notFound) . js::locate('back'));
@@ -246,6 +249,10 @@ class productplan extends control
$this->session->set('storyList', $this->app->getURI(true) . '&type=' . 'story');
$this->session->set('bugList', $this->app->getURI(true) . '&type=' . 'bug');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
$reSort = false;
if($type == 'story' && strpos($orderBy, 'order') !== false)
{
@@ -259,7 +266,9 @@ class productplan extends control
$this->commonAction($plan->product, $plan->branch);
$products = $this->product->getPairs();
$planStories = $this->loadModel('story')->getPlanStories($planID, 'all', $type == 'story' ? $sort : 'id_desc');
$bugPager = new pager($type == 'bug' ? $recTotal : 0, $recPerPage, $type == 'bug' ? $pageID : 1);
$storyPager = new pager($type == 'story' ? $recTotal : 0, $recPerPage, $type == 'story' ? $pageID : 1);
$planStories = $this->loadModel('story')->getPlanStories($planID, 'all', $type == 'story' ? $sort : 'id_desc', $storyPager);
if($reSort)
{
if(!empty($plan->order))
@@ -290,7 +299,7 @@ class productplan extends control
$this->view->title = "PLAN #$plan->id $plan->title/" . $products[$plan->product];
$this->view->position[] = $this->lang->productplan->view;
$this->view->planStories = $planStories;
$this->view->planBugs = $this->loadModel('bug')->getPlanBugs($planID, 'all', $type == 'bug' ? $sort : 'id_desc');
$this->view->planBugs = $this->loadModel('bug')->getPlanBugs($planID, 'all', $type == 'bug' ? $sort : 'id_desc', $bugPager);
$this->view->products = $products;
$this->view->summary = $this->product->summary($this->view->planStories);
$this->view->plan = $plan;
@@ -302,6 +311,8 @@ class productplan extends control
$this->view->orderBy = $orderBy;
$this->view->link = $link;
$this->view->param = $param;
$this->view->storyPager = $storyPager;
$this->view->bugPager = $bugPager;
$this->display();
}
@@ -345,11 +356,14 @@ class productplan extends control
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
*
* @access public
* @return void
*/
public function linkStory($planID = 0, $browseType = '', $param = 0, $orderBy = 'id_desc')
public function linkStory($planID = 0, $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
if(!empty($_POST['stories']))
{
@@ -365,6 +379,10 @@ class productplan extends control
$this->commonAction($plan->product, $plan->branch);
$products = $this->product->getPairs();
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build search form. */
$queryID = ($browseType == 'bySearch') ? (int)$param : 0;
unset($this->config->product->search['fields']['product']);
@@ -391,21 +409,19 @@ class productplan extends control
}
$this->loadModel('search')->setSearchParams($this->config->product->search);
$planStories = $this->story->getPlanStories($planID);
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch($plan->product, $plan->branch, $queryID, 'id');
foreach($allStories as $key => $story)
{
if($story->status == 'closed') unset($allStories[$key]);
}
$allStories = $this->story->getBySearch($plan->product, $plan->branch, $queryID, 'id', '', 'story', array_keys($planStories), $pager);
}
else
{
$allStories = $this->story->getProductStories($this->view->product->id, $plan->branch ? "0,{$plan->branch}" : 0, $moduleID = '0', $status = 'draft,active,changed', 'story', 'id_desc', null, $hasParent = false);
$allStories = $this->story->getProductStories($this->view->product->id, $plan->branch ? "0,{$plan->branch}" : 0, $moduleID = '0', $status = 'draft,active,changed', 'story', 'id_desc', $hasParent = false, array_keys($planStories), $pager);
}
$this->view->allStories = $allStories;
$this->view->planStories = $this->story->getPlanStories($planID);
$this->view->planStories = $planStories;
$this->view->products = $products;
$this->view->plan = $plan;
$this->view->plans = $this->dao->select('id, end')->from(TABLE_PRODUCTPLAN)->fetchPairs();
@@ -414,6 +430,7 @@ class productplan extends control
$this->view->modules = $this->loadModel('tree')->getOptionMenu($plan->product);
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->display();
}
@@ -477,11 +494,14 @@ class productplan extends control
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
*
* @access public
* @return void
*/
public function linkBug($planID = 0, $browseType = '', $param = 0, $orderBy = 'id_desc')
public function linkBug($planID = 0, $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
$projects = $this->app->user->view->projects . ',0';
@@ -499,6 +519,10 @@ class productplan extends control
$productID = $plan->product;
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Build the search form. */
$this->config->bug->search['actionURL'] = $this->createLink('productplan', 'view', "planID=$planID&type=bug&orderBy=$orderBy&link=true&param=" . helper::safe64Encode('&browseType=bySearch&queryID=myQueryID'));
$this->config->bug->search['queryID'] = $queryID;
@@ -523,27 +547,26 @@ class productplan extends control
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
$planBugs = $this->bug->getPlanBugs($planID);
if($browseType == 'bySearch')
{
$allBugs = $this->bug->getBySearch($plan->product, $plan->branch, $queryID, 'id_desc');
foreach($allBugs as $key => $bug)
{
if($bug->status != 'active' or $bug->toTask != 0 or $bug->toStory != 0) unset($allBugs[$key]);
}
$allBugs = $this->bug->getBySearch($plan->product, $plan->branch, $queryID, 'id_desc', array_keys($planBugs), $pager);
}
else
{
$allBugs = $this->bug->getActiveBugs($this->view->product->id, $plan->branch, $projects);
$allBugs = $this->bug->getActiveBugs($this->view->product->id, $plan->branch, $projects, array_keys($planBugs), $pager);
}
$this->view->allBugs = $allBugs;
$this->view->planBugs = $this->bug->getPlanBugs($planID);
$this->view->planBugs = $planBugs;
$this->view->products = $products;
$this->view->plan = $plan;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->browseType = $browseType;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
$this->display();
}
+32 -3
View File
@@ -1,16 +1,45 @@
function showLink(planID, type, orderBy, param)
{
var method = type == 'story' ? 'linkStory' : 'linkBug';
$.get(createLink('productplan', method, 'planID=' + planID + (typeof(param) == 'undefined' ? '' : param) + (typeof(orderBy) == 'undefined' ? '' : "&orderBy=" + orderBy)), function(data)
loadURL(createLink('productplan', method, 'planID=' + planID + (typeof(param) == 'undefined' ? '' : param) + (typeof(orderBy) == 'undefined' ? '' : "&orderBy=" + orderBy)), type)
$('.actions').find("a[href*='" + type + "']").addClass('hidden');
}
/**
* Load URL.
*
* @param string $url
* @param string $type
* @access public
* @return void
*/
function loadURL(url, type)
{
$.get(url, function(data)
{
var $pane = $(type == 'story' ? '#stories' : '#bugs');
$pane.find('.main-table').hide();
var $linkBox = $pane.find('.linkBox').html(data).removeClass('hidden');
$linkBox.html(data).removeClass('hidden');
$linkBox.find('[data-ride="table"]').table();
$linkBox.find('[data-ride="pager"]').pager();
$linkBox.find('[data-ride="pager"] li a.pager-item').click(function()
{
loadURL($(this).attr('href'), type);
return false;
});
$linkBox.find('[data-ride="pager"] .pager-size-menu a[data-size]').off('click');
$linkBox.find('[data-ride="pager"] .pager-size-menu a[data-size]').click(function()
{
line = $linkBox.find('[data-ride="pager"]').attr('data-link-creator');
line = line.replace('{recPerPage}', $(this).attr('data-size')).replace('{page}', $linkBox.find('[data-ride="pager"]').attr('data-page'));
$.cookie($linkBox.find('[data-ride="pager"]').attr('data-page-cookie'), $(this).attr('data-size'), {expires:config.cookieLife, path:config.webRoot});
loadURL(line, type);
return false;
});
$.toggleQueryBox(true, $linkBox.find('#queryBox'));
});
$('.actions').find("a[href*='" + type + "']").addClass('hidden');
}
$(function()
+1 -1
View File
@@ -37,7 +37,6 @@
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allBugs as $bug):?>
<?php if(isset($planBugs[$bug->id])) continue;?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('bugs', array($bug->id => sprintf('%03d', $bug->id)));?>
@@ -67,6 +66,7 @@
<?php echo html::a(inlink('view', "planID=$plan->id&type=bug&orderBy=$orderBy"), $lang->goback, '', "class='btn'");?>
</div>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
</div>
+1 -2
View File
@@ -41,8 +41,6 @@
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allStories as $story):?>
<?php if($story->parent < 0) continue;?>
<?php if(isset($planStories[$story->id])) continue;?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('stories', array($story->id => sprintf('%03d', $story->id)));?>
@@ -81,6 +79,7 @@
<?php echo html::a(inlink('view', "planID=$plan->id&type=story&orderBy=$orderBy"), $lang->goback, '', "class='btn'");?>
</div>
<div class='table-statistic'></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
</div>
+10
View File
@@ -342,6 +342,11 @@
</div>
<?php endif;?>
<div class='text'><?php echo $summary;?></div>
<?php
$this->app->rawParams['type'] = 'story';
$storyPager->show('right', 'pagerjs');
$this->app->rawParams['type'] = $type;
?>
</div>
<?php endif;?>
</form>
@@ -416,6 +421,11 @@
</div>
<?php endif;?>
<div class='text'><?php echo sprintf($lang->productplan->bugSummary, count($planBugs));?></div>
<?php
$this->app->rawParams['type'] = 'bug';
$bugPager->show('right', 'pagerjs');
$this->app->rawParams['type'] = $type;
?>
</div>
<?php endif;?>
</form>
+1 -1
View File
@@ -2053,7 +2053,7 @@ class project extends control
}
else
{
$allStories = $this->story->getProductStories(array_keys($products), $branches, $moduleID = '0', $status = 'active', 'story', 'id_desc', $pager = null, $hasParent = false);
$allStories = $this->story->getProductStories(array_keys($products), $branches, $moduleID = '0', $status = 'active', 'story', 'id_desc', $hasParent = false, '', $pager = null);
}
foreach($allStories as $id => $story)
{
+1
View File
@@ -2962,6 +2962,7 @@ class projectModel extends model
$buttons .= common::buildIconButton('task', 'assignTo', "projectID=$task->project&taskID=$task->id", $task, 'list', '', '', 'iframe', true);
$buttons .= common::buildIconButton('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
$buttons .= common::buildIconButton('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
if(isset($task->children)) $taskItem->children = $this->formatTasksForTree($task->children);
if($taskItem->storyChanged)
{
+1 -1
View File
@@ -421,7 +421,7 @@ class release extends control
}
else
{
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byModule', 0, 'story', $release->stories, $pager);
$allStories = $this->story->getProjectStories($build->project, 't1.`order`_desc', 'byProduct', $release->product, 'story', $release->stories, $pager);
}
$this->view->allStories = $allStories;
-1
View File
@@ -41,7 +41,6 @@ $formID = $type == 'leftBug' ? 'unlinkedLeftBugsForm' : 'unlinkedBugsForm';
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allBugs as $bug):?>
<?php if(strpos(",{$releaseBugs},", ",$bug->id,") !== false) continue;?>
<tr>
<td class='c-id text-left'>
<?php echo html::checkbox('bugs', array($bug->id => sprintf('%03d', $bug->id)), ($type == 'leftBug' or $bug->status == 'resolved' or $bug->status == 'closed') ? $bug->id : '');?>
-2
View File
@@ -39,8 +39,6 @@
<tbody class='text-center'>
<?php $unlinkedCount = 0;?>
<?php foreach($allStories as $story):?>
<?php if(strpos(",{$release->stories},", ",{$story->id},") !== false) continue; ?>
<?php if($release->product != $story->product) continue; ?>
<tr>
<td class='c-id text-left'>
<div class="checkbox-primary">
@@ -50,6 +50,7 @@ if(isset($entry)) $pathInfo .= '&type=file';
</tbody>
</table>
<div class='table-footer'>
<?php echo html::hidden('isPost', true);?>
<?php if(common::hasPriv('repo', 'diff')) echo html::submitButton($lang->repo->diff, '', count($revisions) < 2 ? 'disabled btn btn-primary' : 'btn btn-primary')?>
<?php echo html::a($this->repo->createLink('log', "repoID=$repoID&entry=&revision=HEAD&type=$logType", "entry=" . $this->repo->encodePath($path)), $lang->repo->allLog, '', "class='allLogs'");?>
<div class='pull-right'>
+4 -1
View File
@@ -82,7 +82,10 @@
</tbody>
</table>
<div class='table-footer'>
<?php echo html::submitButton($lang->repo->diff, '', 'btn btn-primary')?>
<?php
echo html::hidden('isPost', true);
echo html::submitButton($lang->repo->diff, '', 'btn btn-primary');
?>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
+6 -3
View File
@@ -1649,13 +1649,14 @@ class storyModel extends model
* @param string $status
* @param string $type requirement|story
* @param string $orderBy
* @param array|string $excludeStories
* @param object $pager
* @param bool $hasParent
*
* @access public
* @return array
*/
public function getProductStories($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $type = 'story', $orderBy = 'id_desc', $pager = null, $hasParent = true)
public function getProductStories($productID = 0, $branch = 0, $moduleIdList = 0, $status = 'all', $type = 'story', $orderBy = 'id_desc', $hasParent = true, $excludeStories = '', $pager = null)
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getStories();
@@ -1670,6 +1671,7 @@ class storyModel extends model
->beginIF(!$hasParent)->andWhere("parent")->ge(0)->fi()
->beginIF($branch)->andWhere("branch")->in($branch)->fi()
->beginIF(!empty($moduleIdList))->andWhere('module')->in($moduleIdList)->fi()
->beginIF(!empty($excludeStories))->andWhere('id')->notIN($excludeStories)->fi()
->beginIF($status and $status != 'all')->andWhere('status')->in($status)->fi()
->andWhere('deleted')->eq(0)
->andWhere('type')->eq($type)
@@ -1907,7 +1909,8 @@ class storyModel extends model
$queryProductID = 'all';
}
$storyQuery = $storyQuery . ' AND `product` ' . helper::dbIN(array_keys($products));
if($excludeStories) $storyQuery = $storyQuery . ' AND `product` NOT ' . helper::dbIN($excludeStories);
if($excludeStories) $storyQuery = $storyQuery . ' AND `id` NOT ' . helper::dbIN($excludeStories);
if($this->app->moduleName == 'productplan') $storyQuery .= " AND `status` NOT IN ('closed') AND `parent` >= 0 ";
if($projectID != '')
{
foreach($products as $product) $branches[$product->branch] = $product->branch;
@@ -2275,7 +2278,7 @@ class storyModel extends model
*/
public function getZeroCase($productID, $orderBy = 'id_desc')
{
$allStories = $this->getProductStories($productID, 0, 0, 'all', 'story', $orderBy, null, $hasParent = false);
$allStories = $this->getProductStories($productID, 0, 0, 'all', 'story', $orderBy, $hasParent = false, '', null);
$casedStories = $this->dao->select('DISTINCT story')->from(TABLE_CASE)->where('product')->eq($productID)->andWhere('story')->ne(0)->andWhere('deleted')->eq(0)->fetchAll('story');
foreach($allStories as $key => $story)
+2 -2
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long