* code for task #2522,2579.

This commit is contained in:
wangyidong
2016-04-20 14:51:05 +08:00
parent 164f7630d3
commit d89d674cdd
29 changed files with 385 additions and 173 deletions

View File

@@ -19,3 +19,4 @@ ALTER TABLE `zt_task` ADD `color` char(7) COLLATE 'utf8_general_ci' NOT NULL AFT
ALTER TABLE `zt_story` ADD `color` char(7) COLLATE 'utf8_general_ci' NOT NULL AFTER `status`;
ALTER TABLE `zt_bug` ADD `color` char(7) COLLATE 'utf8_general_ci' NOT NULL AFTER `status`;
ALTER TABLE `zt_case` ADD `color` char(7) COLLATE 'utf8_general_ci' NOT NULL AFTER `status`;
ALTER TABLE `zt_userquery` ADD `shortcut` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '0';

View File

@@ -105,8 +105,10 @@ class bug extends control
$bugs = $this->bug->processBuildForBugs($bugs);
/* Build the search form. */
$this->config->bug->search['style'] = 'shortcut';
$actionURL = $this->createLink('bug', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
$this->bug->buildSearchForm($productID, $this->products, $queryID, $actionURL);
$this->loadModel('search')->mergeFeatureBar('bug', 'browse');
$showModule = !empty($this->config->datatable->bugbrowse->showModule) ? $this->config->datatable->bugbrowse->showModule : '';
$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'bug', $showModule) : array();

View File

@@ -1,7 +1,5 @@
$(document).ready(function()
{
$('#' + bugBrowseType + 'Tab').addClass('active');
$('#module' + moduleID).addClass('active');
if(browseType == 'bysearch') ajaxGetSearchForm();
$('.dropdown-menu .with-search .menu-search').click(function(e)

View File

@@ -224,7 +224,7 @@ class bugModel extends model
{
/* Set modules and browse type. */
$modules = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
$browseType = (($browseType == 'bymodule') and ($this->session->bugBrowseType) and ($this->session->bugBrowseType != 'bysearch')) ? $this->session->bugBrowseType : $browseType;
$browseType = ($browseType == 'bymodule' and $this->session->bugBrowseType and $this->session->bugBrowseType != 'bysearch') ? $this->session->bugBrowseType : $browseType;
/* Get bugs by browse type. */
$bugs = array();

View File

@@ -15,7 +15,7 @@ include '../../common/view/header.html.php';
include '../../common/view/datatable.fix.html.php';
js::set('browseType', $browseType);
js::set('moduleID', $moduleID);
js::set('bugBrowseType', $this->session->bugBrowseType);
js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrowseType == 'bysearch') ? 'all' : $this->session->bugBrowseType);
?>
<div id='featurebar'>
<ul class='nav'>
@@ -34,7 +34,12 @@ js::set('bugBrowseType', $this->session->bugBrowseType);
</li>
<?php foreach($app->customMenu['featurebar'] as $type => $featurebar):?>
<?php if($featurebar['status'] == 'hide') continue;?>
<?php if(strpos($type, 'QUERY') === 0):?>
<?php $queryID = (int)substr($type, 5);?>
<li id='<?php echo $type?>Tab'><?php echo html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=bySearch&param=$queryID"), $featurebar['link'])?></li>
<?php else:?>
<li id='<?php echo $type?>Tab'><?php echo html::a($this->createLink('bug', 'browse', "productid=$productID&branch=$branch&browseType=$type&param=0"), $featurebar['link'])?></li>
<?php endif;?>
<?php endforeach;?>
<li id='bysearchTab'><a href='#'><i class='icon-search icon'></i>&nbsp;<?php echo $lang->bug->byQuery;?></a></li>
</ul>
@@ -211,14 +216,20 @@ js::set('bugBrowseType', $this->session->bugBrowseType);
</form>
</div>
<script>
<?php
$this->app->loadConfig('qa', '', false);
if($this->config->qa->homepage != 'browse'):
?>
$(function()
$('#' + bugBrowseType + 'Tab').addClass('active');
$('#module' + moduleID).addClass('active');
<?php if($browseType == 'bysearch'):?>
$shortcut = $('#QUERY<?php echo (int)$param;?>Tab');
if($shortcut.size() > 0)
{
$('#modulemenu .nav li:last').after("<li class='right'><a href='javascript:setHomepage(\"qa\", \"browse\")'><i class='icon icon-home'></i><?php echo $lang->homepage?></a></li>")
});
$shortcut.addClass('active');
$('#bysearchTab').removeClass('active');
$('#querybox').removeClass('show');
}
<?php endif;?>
<?php $this->app->loadConfig('qa', '', false);?>
<?php if($this->config->qa->homepage != 'browse'):?>
$(function(){$('#modulemenu .nav li:last').after("<li class='right'><a href='javascript:setHomepage(\"qa\", \"browse\")'><i class='icon icon-home'></i><?php echo $lang->homepage?></a></li>")});
<?php endif;?>
</script>
<?php include '../../common/view/footer.html.php';?>

View File

@@ -141,7 +141,7 @@ $(document).ready(function()
$exportFieldPairs[$field] = isset($moduleLang->$field) ? $moduleLang->$field : (isset($lang->$field) ? $lang->$field : $field);
}
?>
<div class='panel' id='customFields'style='margin-bottom:150px'>
<div class='panel' id='customFields' style='margin-bottom:150px'>
<div class='panel-heading'><strong><?php echo $lang->file->exportFields?></strong></div>
<div class='panel-body'>
<p><?php echo html::select('exportFields[]', $exportFieldPairs, $selectedFields, "class='form-control chosen' multiple")?></p>

View File

@@ -143,8 +143,10 @@ class product extends control
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
/* Build search form. */
$this->config->product->search['style'] = 'shortcut';
$actionURL = $this->createLink('product', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
$this->product->buildSearchForm($productID, $this->products, $queryID, $actionURL);
$this->loadModel('search')->mergeFeatureBar('product', 'browse');
$showModule = !empty($this->config->datatable->productbrowse->showModule) ? $this->config->datatable->productbrowse->showModule : '';
$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'story', $showModule) : array();
@@ -172,6 +174,7 @@ class product extends control
$this->view->branches = $this->loadModel('branch')->getPairs($productID);
$this->view->storyStages = $this->product->batchGetStoryStage($stories);
$this->view->setShowModule = true;
$this->view->param = $param;
$this->display();
}

View File

@@ -367,7 +367,7 @@ class productModel extends model
/* Set modules and browse type. */
$modules = $moduleID ? $this->loadModel('tree')->getAllChildID($moduleID) : '0';
$browseType = (($browseType == 'bymodule') and ($this->session->storyBrowseType) and ($this->session->storyBrowseType != 'bysearch')) ? $this->session->storyBrowseType : $browseType;
$browseType = ($browseType == 'bymodule' and $this->session->storyBrowseType and $this->session->storyBrowseType != 'bysearch') ? $this->session->storyBrowseType : $browseType;
/* Get stories by browseType. */
$stories = array();

View File

@@ -30,7 +30,12 @@
</li>
<?php foreach($app->customMenu['featurebar'] as $type => $featurebar):?>
<?php if($featurebar['status'] == 'hide') continue;?>
<?php if(strpos($type, 'QUERY') === 0):?>
<?php $queryID = (int)substr($type, 5);?>
<li id='<?php echo $type?>Tab'><?php echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=bySearch&param=$queryID"), $featurebar['link']);?></li>
<?php else:?>
<li id='<?php echo $type?>Tab'><?php echo html::a($this->inlink('browse', "productID=$productID&branch=$branch&browseType=$type"), $featurebar['link']);?></li>
<?php endif;?>
<?php endforeach;?>
<li id='bysearchTab'><a href='javascript:;'><i class='icon-search icon'></i> <?php echo $lang->product->searchStory;?></a></li>
</ul>
@@ -79,7 +84,7 @@
<?php
$datatableId = $this->moduleName . $this->methodName;
$useDatatable = (isset($this->config->datatable->$datatableId->mode) and $this->config->datatable->$datatableId->mode == 'datatable');
$vars = "productID=$productID&branch=$branch&browseType=$browseType&param=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
$vars = "productID=$productID&branch=$branch&browseType=$browseType&param=$param&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
include $useDatatable ? dirname(__FILE__) . '/datatabledata.html.php' : dirname(__FILE__) . '/browsedata.html.php';
?>
<tfoot>
@@ -254,7 +259,16 @@
</div>
<script language='javascript'>
$('#module<?php echo $moduleID;?>').addClass('active');
$('#<?php echo $this->session->storyBrowseType;?>Tab').addClass('active');
$('#<?php echo ($browseType == 'bymodule' and $this->session->storyBrowseType == 'bysearch') ? 'all' : $this->session->storyBrowseType;?>Tab').addClass('active');
<?php if($browseType == 'bysearch'):?>
$shortcut = $('#QUERY<?php echo (int)$param;?>Tab');
if($shortcut.size() > 0)
{
$shortcut.addClass('active');
$('#bysearchTab').removeClass('active');
$('#querybox').removeClass('show');
}
<?php endif;?>
<?php if($this->config->product->homepage != 'browse'):?>
$('#modulemenu .nav li.right:last').after("<li class='right'><a href='javascript:setHomepage(\"product\", \"browse\")'><i class='icon icon-home'></i><?php echo $lang->homepage?></a></li>")
<?php endif;?>

View File

@@ -168,8 +168,10 @@ class project extends control
$tasks = $this->project->getTasks($productID, $projectID, $this->projects, $browseType, $queryID, $moduleID, $sort, $pager);
/* Build the search form. */
$this->config->project->search['style'] = 'shortcut';
$actionURL = $this->createLink('project', 'task', "projectID=$projectID&status=bySearch&param=myQueryID");
$this->project->buildSearchForm($projectID, $this->projects, $queryID, $actionURL);
$this->loadModel('search')->mergeFeatureBar('project', 'task');
/* team member pairs. */
$memberPairs = array();

View File

@@ -4,6 +4,7 @@
#hideButton{cursor:pointer;}
#hideButton span{padding:2px 10px; background:url(theme/default/images/main/zt-icons.png) -100px -161px;}
#featurebar .f-right .icon-green-task-import {padding:2px 8px; background:url(theme/default/images/main/zt-icons.png) 0px -82px;}
.sub-featurebar #querybox {margin:0px;}
.dropdown-menu.with-search {padding-bottom: 34px; min-width: 150px; overflow: hidden; max-height: 305px}
.dropdown-menu > .menu-search {padding: 0; position: absolute; z-index: 0; bottom: 0; left: 0; right: 0}

View File

@@ -123,20 +123,17 @@ $lang->project->importTask = '转入任务';
$lang->project->importBug = '导入Bug';
$lang->project->updateOrder = '排序';
$lang->project->tree = '树视图';
$lang->project->list = '列表';
/* 分组浏览。*/
$lang->project->allTasks = '所有';
$lang->project->assignedToMe = '指派给我';
$lang->project->statusSelects[''] = '更多';
$lang->project->statusSelects['finishedbyme'] = '我完成';
$lang->project->statusSelects['wait'] = '未开始';
$lang->project->statusSelects['doing'] = '进行中';
$lang->project->statusSelects['undone'] = '未完成';
$lang->project->statusSelects['done'] = '已完成';
$lang->project->statusSelects['closed'] = '已关闭';
$lang->project->statusSelects['delayed'] = '已延期';
$lang->project->statusSelects['needconfirm'] = '需求变动';
$lang->project->statusSelects['cancel'] = '已取消';
$lang->project->groups[''] = '分组查看';
@@ -253,14 +250,10 @@ $lang->printKanban->typeList['increment'] = '增量';
$lang->project->featurebar['task']['unclosed'] = $lang->project->unclosed;
$lang->project->featurebar['task']['all'] = $lang->project->allTasks;
$lang->project->featurebar['task']['kanban'] = $lang->project->kanban;
$lang->project->featurebar['task']['burn'] = $lang->project->burn;
$lang->project->featurebar['task']['assignedtome'] = $lang->project->assignedToMe;
$lang->project->featurebar['task']['finishedbyme'] = '我完成';
$lang->project->featurebar['task']['delayed'] = '已延期';
$lang->project->featurebar['task']['needconfirm'] = '需求变动';
$lang->project->featurebar['task']['status'] = $lang->project->statusSelects[''];
$lang->project->featurebar['task']['group'] = $lang->project->groups[''];
$lang->project->featurebar['grouptask'] = $lang->project->featurebar['task'];
$lang->project->featurebar['kanban'] = $lang->project->featurebar['task'];
$lang->project->featurebar['burn'] = $lang->project->featurebar['task'];
$lang->project->treeLevel = array();
$lang->project->treeLevel['product'] = array('icon' => 'icon-cube', 'text' => '产品视图');

View File

@@ -19,6 +19,67 @@ js::set('moduleID', $moduleID);
js::set('productID', $productID);
js::set('browseType', $browseType);
?>
<div class='sub-featurebar'>
<ul class='nav'>
<li style='padding-top:5px;'>
<span>
<?php
if($productID)
{
$product = $this->product->getById($productID);
$removeLink = $browseType == 'byproduct' ? inlink('task', "projectID=$projectID&browseType=$status&param=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("browseParam")';
echo $product->name;
echo '&nbsp;' . html::a($removeLink, "<i class='icon icon-remove'></i>") . '&nbsp;';
}
elseif($moduleID)
{
$module = $this->tree->getById($moduleID);
$removeLink = $browseType == 'bymodule' ? inlink('task', "projectID=$projectID&browseType=$status&param=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("browseParam")';
echo $module->name;
echo '&nbsp;' . html::a($removeLink, "<i class='icon icon-remove'></i>") . '&nbsp;';
}
else
{
echo $this->lang->tree->all;
}
echo " <i class='icon-angle-right'></i>&nbsp; ";
?>
</span>
</li>
<?php foreach($app->customMenu['featurebar'] as $type => $featurebar):?>
<?php
if($featurebar['status'] == 'hide') continue;
if(strpos($type, 'QUERY') === 0)
{
$queryID = (int)substr($type, 5);
echo "<li id='{$type}Tab'>" . html::a(inlink('task', "project=$projectID&type=bySearch&param=$queryID"), $featurebar['link']) . '</li>' ;
}
elseif($type != 'status')
{
echo "<li id='{$type}Tab'>" . html::a(inlink('task', "project=$projectID&type=$type"), $featurebar['link']) . '</li>' ;
}
elseif($type == 'status')
{
echo "<li id='statusTab' class='dropdown'>";
$taskBrowseType = isset($status) ? $this->session->taskBrowseType : '';
$current = zget($lang->project->statusSelects, $taskBrowseType, '');
if(empty($current)) $current = $featurebar['link'];
echo html::a('javascript:;', $current . " <span class='caret'></span>", '', "data-toggle='dropdown'");
echo "<ul class='dropdown-menu'>";
foreach ($lang->project->statusSelects as $key => $value)
{
if($key == '') continue;
echo '<li' . ($key == $taskBrowseType ? " class='active'" : '') . '>';
echo html::a($this->createLink('project', 'task', "project=$projectID&type=$key"), $value);
}
echo '</ul></li>';
}
?>
<?php endforeach;?>
<?php echo "<li id='bysearchTab'><a href='#'><i class='icon-search icon'></i>&nbsp;{$lang->project->byQuery}</a></li> ";?>
</ul>
<div id='querybox' class='<?php if($browseType == 'bysearch') echo 'show';?>'></div>
</div>
<div class='side' id='taskTree'>
<a class='side-handle' data-id='projectTree'><i class='icon-caret-left'></i></a>
@@ -123,7 +184,17 @@ js::set('browseType', $browseType);
<?php js::set('replaceID', 'taskList')?>
<script language='javascript'>
$('#project<?php echo $projectID;?>').addClass('active')
$('#<?php echo $this->session->taskBrowseType;?>Tab').addClass('active')
$('#listTab').addClass('active')
$('#<?php echo ($browseType == 'bymodule' and $this->session->taskBrowseType == 'bysearch') ? 'all' : $this->session->taskBrowseType;?>Tab').addClass('active');
<?php if($browseType == 'bysearch'):?>
$shortcut = $('#QUERY<?php echo (int)$param;?>Tab');
if($shortcut.size() > 0)
{
$shortcut.addClass('active');
$('#bysearchTab').removeClass('active');
$('#querybox').removeClass('show');
}
<?php endif;?>
statusActive = '<?php echo isset($lang->project->statusSelects[$this->session->taskBrowseType]);?>';
if(statusActive) $('#statusTab').addClass('active')
<?php if($this->config->project->homepage != 'browse'):?>

View File

@@ -1,82 +1,23 @@
<div id='featurebar'>
<ul class='nav'>
<li>
<span>
<?php
if($productID)
{
$product = $this->product->getById($productID);
$removeLink = $browseType == 'byproduct' ? inlink('task', "projectID=$projectID&browseType=$status&param=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("browseParam")';
echo $product->name;
echo '&nbsp;' . html::a($removeLink, "<i class='icon icon-remove'></i>") . '&nbsp;';
}
elseif($moduleID)
{
$module = $this->tree->getById($moduleID);
$removeLink = $browseType == 'bymodule' ? inlink('task', "projectID=$projectID&browseType=$status&param=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("browseParam")';
echo $module->name;
echo '&nbsp;' . html::a($removeLink, "<i class='icon icon-remove'></i>") . '&nbsp;';
}
else
{
echo $this->lang->tree->all;
}
echo " <i class='icon-angle-right'></i>&nbsp; ";
?>
</span>
</li>
<?php
$hasBrowsePriv = common::hasPriv('project', 'task');
$hasKanbanPriv = common::hasPriv('project', 'kanban');
$hasBurnPriv = common::hasPriv('project', 'burn');
$hasGroupTaskPriv = common::hasPriv('project', 'groupTask');
$hasTreePriv = common::hasPriv('project', 'tree');
?>
<?php foreach($app->customMenu['featurebar'] as $type => $featurebar):?>
<?php
if($featurebar['status'] == 'hide') continue;
if($hasBrowsePriv and ($type == 'unclosed' or $type == 'all' or $type == 'assignedtome')) echo "<li id='{$type}Tab'>" . html::a(inlink('task', "project=$projectID&type=$type"), $featurebar['link']) . '</li>' ;
if($hasKanbanPriv and $type == 'kanban') echo "<li id='kanbanTab'>" . html::a(inlink('kanban', "projectID=$projectID"), $featurebar['link']) . '</li>';
if($hasBurnPriv and $type == 'burn' and ($project->type == 'sprint' or $project->type == 'waterfall')) echo "<li id='burnTab'>" . html::a(inlink('burn', "project=$projectID"), $featurebar['link']) . '</li>' ;
if($hasTreePriv and $type == 'tree') echo "<li id='treeTab'>"; common::printLink('project', 'tree', "projectID=$projectID", $lang->project->tree, '', '', false); echo '</li>';
if($hasBrowsePriv and $type == 'status')
echo "<li id='listTab'>"; common::printLink('project', 'task', "project=$projectID&type=unclosed", $lang->project->list); echo '</li>';
echo "<li id='kanbanTab'>"; common::printLink('product', 'kanban', "projectID=$projectID", $lang->project->kanban) . '</li>';
if($project->type == 'sprint' or $project->type == 'waterfall') echo "<li id='burnTab'>"; common::printLink('project', 'burn', "project=$projectID", $lang->project->burn); echo '</li>';
echo "<li id='treeTab'>"; common::printLink('project', 'tree', "projectID=$projectID", $lang->project->tree); echo '</li>';
echo "<li id='groupTab' class='dropdown'>";
$groupBy = isset($groupBy) ? $groupBy : '';
$current = zget($lang->project->groups, isset($groupBy) ? $groupBy : '', '');
if(empty($current)) $current = $featurebar['link'];
echo html::a('javascript:;', $current . " <span class='caret'></span>", '', "data-toggle='dropdown'");
echo "<ul class='dropdown-menu'>";
foreach ($lang->project->groups as $key => $value)
{
echo "<li id='statusTab' class='dropdown'>";
$taskBrowseType = isset($status) ? $this->session->taskBrowseType : '';
$current = zget($lang->project->statusSelects, $taskBrowseType, '');
if(empty($current)) $current = $featurebar['link'];
echo html::a('javascript:;', $current . " <span class='caret'></span>", '', "data-toggle='dropdown'");
echo "<ul class='dropdown-menu'>";
foreach ($lang->project->statusSelects as $key => $value)
{
if($key == '') continue;
echo '<li' . ($key == $taskBrowseType ? " class='active'" : '') . '>';
echo html::a($this->createLink('project', 'task', "project=$projectID&type=$key"), $value);
}
echo '</ul></li>';
if($key == '') continue;
echo '<li' . ($key == $groupBy ? " class='active'" : '') . '>';
common::printLink('project', 'groupTask', "project=$projectID&groupBy=$key", $value);
}
elseif($hasGroupTaskPriv and $type == 'group')
{
echo "<li id='groupTab' class='dropdown'>";
$groupBy = isset($groupBy) ? $groupBy : '';
$current = zget($lang->project->groups, isset($groupBy) ? $groupBy : '', '');
if(empty($current)) $current = $featurebar['link'];
echo html::a('javascript:;', $current . " <span class='caret'></span>", '', "data-toggle='dropdown'");
echo "<ul class='dropdown-menu'>";
foreach ($lang->project->groups as $key => $value)
{
if($key == '') continue;
echo '<li' . ($key == $groupBy ? " class='active'" : '') . '>';
echo html::a($this->createLink('project', 'groupTask', "project=$projectID&groupBy=$key"), $value);
}
echo '</ul></li>';
}
?>
<?php endforeach;?>
<?php
if($this->methodName == 'task') echo "<li id='bysearchTab'><a href='#'><i class='icon-search icon'></i>&nbsp;{$lang->project->byQuery}</a></li> ";
echo '</ul></li>';
?>
</ul>
<div class='actions'>
@@ -126,7 +67,6 @@
?>
</div>
</div>
<div id='querybox' class='<?php if($browseType == 'bysearch') echo 'show';?>'></div>
</div>
<?php
$headerHooks = glob(dirname(dirname(__FILE__)) . "/ext/view/featurebar.*.html.hook.php");

View File

@@ -99,4 +99,30 @@ class search extends control
$queries = $this->search->getQueryPairs($module);
die(html::select('queryID', $queries, $query, 'onchange=executeQuery(this.value) class=form-control'));
}
/**
* Ajax save shortcut.
*
* @param strint $module
* @access public
* @return void
*/
public function ajaxSaveShortcut($module)
{
$queries = $this->search->getQueryPairs($module);
if($this->server->request_method == 'POST')
{
$shortcuts = empty($_POST['shortcuts']) ? array() : $_POST['shortcuts'];
foreach($queries as $queryID => $query)
{
$shortcut = ($shortcuts and in_array($queryID, $shortcuts)) ? 1 : 0;
$this->dao->update(TABLE_USERQUERY)->set('shortcut')->eq($shortcut)->where('id')->eq($queryID)->exec();
}
die(js::reload('parent.parent'));
}
$this->view->queries = $queries;
$this->view->shortcuts = $this->search->getShorcutQueryPairs($module);
$this->display();
}
}

View File

@@ -22,6 +22,10 @@ $lang->search->deleteQuery = '删除查询';
$lang->search->setQueryTitle = '请输入查询标题(保存之前请先查询):';
$lang->search->select = '需求/任务筛选';
$lang->search->me = '自己';
$lang->search->shortcut = '快捷';
$lang->search->noQuery = '还没有保存查询!';
$lang->search->noticeShortcut = '设置快捷访问,可以将保存的查询固定到列表导航,方便查看!';
$lang->search->operators['='] = '=';
$lang->search->operators['!='] = '!=';

View File

@@ -292,6 +292,23 @@ class searchModel extends model
return $queries;
}
/**
* Get shorcut query pairs.
*
* @param string $module
* @access public
* @return array
*/
public function getShorcutQueryPairs($module)
{
return $this->dao->select('id, title')->from(TABLE_USERQUERY)
->where('account')->eq($this->app->user->account)
->andWhere('module')->eq($module)
->andWhere('shortcut')->eq(1)
->orderBy('id_asc')
->fetchPairs();
}
/**
* Get records by the conditon.
*
@@ -390,4 +407,23 @@ class searchModel extends model
}
return $query;
}
/**
* Merge shortcut query in featureBar.
*
* @param string $module
* @param string $method
* @access public
* @return void
*/
public function mergeFeatureBar($module, $method)
{
$queryModule = $module == 'project' ? 'task' : ($module == 'product' ? 'story' : $module);
$shortcuts = $this->getShorcutQueryPairs($queryModule);
foreach($shortcuts as $id => $name)
{
$shortcutID = 'QUERY' . $id;
$this->lang->$module->featurebar[$method][$shortcutID] = $name;
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* The ajaxSaveShortcut view file of search module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package search
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php include '../../common/view/chosen.html.php';?>
<?php unset($queries['']);?>
<?php if(empty($queries)):?>
<p><?php echo $lang->search->noQuery?></p>
<?php else:?>
<form class='form-condensed' method='post' target='hiddenwin' style='padding: 40px 5% 150px;'>
<div class='input-group'>
<?php echo html::select('shortcuts[]', $queries, array_keys($shortcuts), "class='form-control chosen' multiple");?>
<span class='input-group-btn'><?php echo html::submitButton()?></span>
</div>
<div class='alert alert-info' style='margin-top:5px'><?php echo $lang->search->noticeShortcut?></div>
</form>
<?php endif;?>
<?php include '../../common/view/footer.lite.html.php';?>

View File

@@ -398,7 +398,7 @@ foreach($fieldParams as $fieldName => $param)
?>
</table>
</td>
<td class='<?php echo $style == 'simple' ? 'w-80px' : 'w-160px'?>'>
<td class='<?php echo $style == 'simple' ? 'w-80px' : ($style == 'shortcut' ? 'w-180px' : 'w-160px');?>'>
<?php
echo html::hidden('module', $module);
echo html::hidden('actionURL', $actionURL);
@@ -410,6 +410,7 @@ foreach($fieldParams as $fieldName => $param)
echo html::commonButton($lang->search->reset, 'onclick=resetForm(this)');
echo html::commonButton($lang->save, 'onclick=saveQuery()');
}
if($style == 'shortcut') echo html::a($this->createLink('search', 'ajaxSaveShortcut', "module=$module"), $lang->search->shortcut, '', "class='btn' id='shortcutModal'");
echo '</div>';
?>
</td>
@@ -430,5 +431,6 @@ foreach($fieldParams as $fieldName => $param)
</div>
</form>
<script language='Javascript'>
$("#shortcutModal").modalTrigger({width:650, type:'iframe'});
<?php if(isset($formSession['formType'])) echo "show{$formSession['formType']}('#{$module}-search')";?>
</script>

View File

@@ -95,8 +95,10 @@ class testcase extends control
$cases = $this->loadModel('story')->checkNeedConfirm($cases);
/* Build the search form. */
$this->config->testcase->search['style'] = 'shortcut';
$actionURL = $this->createLink('testcase', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID");
$this->testcase->buildSearchForm($productID, $this->products, $queryID, $actionURL);
$this->loadModel('search')->mergeFeatureBar('testcase', 'browse');
$showModule = !empty($this->config->datatable->testcasebrowse->showModule) ? $this->config->datatable->testcasebrowse->showModule : '';
$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'case', $showModule) : array();

View File

@@ -23,8 +23,6 @@ function confirmBatchDelete(actionLink)
$(document).ready(function()
{
$('#' + caseBrowseType + 'Tab').addClass('active');
$('#module' + moduleID).addClass('active');
if(browseType == 'bysearch') ajaxGetSearchForm();
setTimeout(function(){fixedTfootAction('#batchForm')}, 100);
setTimeout(function(){fixedTheadOfList('#caseList')}, 100);

View File

@@ -262,7 +262,7 @@ class testcaseModel extends model
{
/* Set modules and browse type. */
$modules = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
$browseType = (($browseType == 'bymodule') and ($this->session->caseBrowseType) and ($this->session->caseBrowseType != 'bysearch')) ? $this->session->caseBrowseType : $browseType;
$browseType = ($browseType == 'bymodule' and $this->session->caseBrowseType and $this->session->caseBrowseType != 'bysearch') ? $this->session->caseBrowseType : $browseType;
/* By module or all cases. */
$cases = array();

View File

@@ -16,7 +16,7 @@ include '../../common/view/datepicker.html.php';
include '../../common/view/datatable.fix.html.php';
include './caseheader.html.php';
js::set('browseType', $browseType);
js::set('caseBrowseType', $this->session->caseBrowseType);
js::set('caseBrowseType', ($browseType == 'bymodule' and $this->session->caseBrowseType == 'bysearch') ? 'all' : $this->session->caseBrowseType);
js::set('moduleID' , $moduleID);
js::set('confirmDelete', $lang->testcase->confirmDelete);
js::set('batchDelete', $lang->testcase->confirmBatchDelete);
@@ -98,4 +98,17 @@ js::set('batchDelete', $lang->testcase->confirmBatchDelete);
</tfoot>
</form>
</div>
<script>
$('#module' + moduleID).addClass('active');
$('#' + caseBrowseType + 'Tab').addClass('active');
<?php if($browseType == 'bysearch'):?>
$shortcut = $('#QUERY<?php echo (int)$param;?>Tab');
if($shortcut.size() > 0)
{
$shortcut.addClass('active');
$('#bysearchTab').removeClass('active');
$('#querybox').removeClass('show');
}
<?php endif;?>
</script>
<?php include '../../common/view/footer.html.php';?>

View File

@@ -1,12 +1,11 @@
<?php if(!isset($branch)) $branch = 0;?>
<div id='featurebar'>
<ul class='nav'>
<?php if(isset($moduleID)):?>
<li>
<span>
<?php
echo $moduleName;
if($moduleID)
echo isset($moduleID) ? $moduleName : $this->lang->tree->all;
if(!empty($moduleID))
{
$removeLink = $browseType == 'bymodule' ? inlink('browse', "productID=$productID&branch=$branch&browseType=$browseType&param=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("caseModule")';
echo '&nbsp;' . html::a($removeLink, "<i class='icon icon-remove'></i>") . '&nbsp;';
@@ -15,15 +14,24 @@
?>
</span>
</li>
<?php endif;?>
<?php
$hasBrowsePriv = common::hasPriv('testcase', 'browse');
$hasGroupPriv = common::hasPriv('testcase', 'groupcase');
$hasZeroPriv = common::hasPriv('story', 'zerocase');
?>
<?php foreach($app->customMenu['featurebar'] as $type => $featurebar):?>
<?php if($featurebar['status'] == 'hide') continue;?>
<?php
if(common::hasPriv('testcase', 'browse') and ($type == 'all' or $type == 'needconfirm'))
if($hasBrowsePriv and strpos($type, 'QUERY') === 0)
{
$queryID = (int)substr($type, 5);
echo "<li id='{$type}Tab'>" . html::a($this->createLink('testcase', 'browse', "productid=$productID&branch=$branch&browseType=bySearch&param=$queryID"), $featurebar['link']) . "</li>";
}
elseif($hasBrowsePriv and ($type == 'all' or $type == 'needconfirm'))
{
echo "<li id='{$type}Tab'>" . html::a($this->createLink('testcase', 'browse', "productid=$productID&branch=$branch&browseType=$type"), $featurebar['link']) . "</li>";
}
elseif($type == 'group' and common::hasPriv('testcase', 'groupcase'))
elseif($hasGroupPriv and $type == 'group')
{
echo "<li id='groupTab' class='dropdown'>";
$groupBy = isset($groupBy) ? $groupBy : '';
@@ -39,7 +47,7 @@
}
echo '</ul></li>';
}
elseif($type == 'zerocase' and common::hasPriv('story', 'zeroCase'))
elseif($hasZeroPriv and $type == 'zerocase')
{
echo "<li id='zerocaseTab'>" . html::a($this->createLink('story', 'zeroCase', "productID=$productID"), $lang->story->zeroCase) . '</li>';
}

View File

@@ -230,7 +230,11 @@ class testtask extends control
$pager = pager::init($recTotal, $recPerPage, $pageID);
/* Set the browseType and moduleID. */
$browseType = strtolower($browseType);
$moduleID = ($browseType == 'bymodule') ? (int)$param : 0;
if($browseType == 'bymodule') setcookie('taskCaseModule', (int)$param, $this->config->cookieLife, $this->config->webRoot);
if($browseType != 'bymodule') $this->session->set('taskCaseBrowseType', $browseType);
$moduleID = ($browseType == 'bymodule') ? (int)$param : ($browseType == 'bysearch' ? 0 : ($this->cookie->taskCaseModule ? $this->cookie->taskCaseModule : 0));
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
/* Append id for secend sort. */
@@ -241,58 +245,9 @@ class testtask extends control
if(!$task) die(js::error($this->lang->notFound) . js::locate('back'));
$productID = $task->product;
$this->testtask->setMenu($this->products, $productID, $task->branch);
if($browseType == 'bymodule' or $browseType == 'all')
{
$modules = '';
if($moduleID) $modules = $this->loadModel('tree')->getAllChildID($moduleID);
$this->view->runs = $this->testtask->getRuns($taskID, $modules, $sort, $pager);
}
elseif($browseType == 'assignedtome')
{
$this->view->runs = $this->testtask->getUserRuns($taskID, $this->session->user->account, $sort, $pager);
}
/* By search. */
elseif($browseType == 'bysearch')
{
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set('testcaseQuery', $query->sql);
$this->session->set('testcaseForm', $query->form);
}
else
{
$this->session->set('testcaseQuery', ' 1 = 1');
}
}
else
{
if($this->session->testcaseQuery == false) $this->session->set('testcaseQuery', ' 1 = 1');
}
$queryProductID = $productID;
$allProduct = "`product` = 'all'";
$caseQuery = $this->session->testcaseQuery;
if(strpos($this->session->testcaseQuery, $allProduct) !== false)
{
$products = array_keys($this->loadModel('product')->getPrivProducts());
$caseQuery = str_replace($allProduct, '1', $this->session->testcaseQuery);
$caseQuery = $caseQuery . ' AND `product`' . helper::dbIN(array_keys($products));
$queryProductID = 'all';
}
$caseQuery = preg_replace('/`(\w+)`/', 't2.`$1`', $caseQuery);
$this->view->runs = $this->dao->select('t2.*,t1.*, t2.version as caseVersion')->from(TABLE_TESTRUN)->alias('t1')
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
->where($caseQuery)
->andWhere('t1.task')->eq($taskID)
->beginIF($task->branch)->andWhere('t2.branch')->in("0,{$task->branch}")->fi()
->orderBy(strpos($sort, 'assignedTo') !== false ? ('t1.' . $sort) : ('t2.' . $sort))
->page($pager)
->fetchAll();
}
/* Get test cases. */
$this->view->runs = $this->testtask->getTaskCases($productID, $browseType, $queryID, $moduleID, $sort, $pager, $task);
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', false);
/* Save testcaseIDs session for get the pre and next testcase. */
@@ -302,12 +257,15 @@ class testtask extends control
/* Build the search form. */
$this->loadModel('testcase');
$this->config->testcase->search['params']['product']['values']= array($productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct);
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
$this->config->testcase->search['style'] = 'shortcut';
$this->config->testcase->search['module'] = 'testtask';
$this->config->testcase->search['params']['product']['values'] = array($productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct);
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
$this->config->testcase->search['actionURL'] = inlink('cases', "taskID=$taskID&browseType=bySearch&queryID=myQueryID");
unset($this->config->testcase->search['fields']['branch']);
unset($this->config->testcase->search['params']['branch']);
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
$this->search->mergeFeatureBar('testtask', 'cases');
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->cases;
$this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]);
@@ -325,6 +283,7 @@ class testtask extends control
$this->view->orderBy = $orderBy;
$this->view->taskID = $taskID;
$this->view->moduleID = $moduleID;
$this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all;
$this->view->treeClass = $browseType == 'bymodule' ? '' : 'hidden';
$this->view->pager = $pager;
$this->view->branches = $this->loadModel('branch')->getPairs($productID);

View File

@@ -1,8 +1,6 @@
$(document).ready(function()
{
setModal4List('runCase', 'caseList', function(){$(".iframe").modalTrigger({width:1024, type:'iframe'});}, 1024);
$('#' + browseType + 'Tab').addClass('active');
$('#module' + moduleID).addClass('active');
if(browseType == 'bysearch') ajaxGetSearchForm();
setTimeout(function(){fixedTfootAction('#casesForm')}, 100);
});

View File

@@ -282,7 +282,7 @@ class testtaskModel extends model
* @access public
* @return array
*/
public function getUserRuns($taskID, $user, $orderBy, $pager = null)
public function getUserRuns($taskID, $user, $modules = '', $orderBy, $pager = null)
{
$orderBy = strpos($orderBy, 'assignedTo') !== false ? ('t1.' . $orderBy) : ('t2.' . $orderBy);
@@ -290,11 +290,77 @@ class testtaskModel extends model
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
->where('t1.task')->eq((int)$taskID)
->andWhere('t1.assignedTo')->eq($user)
->beginIF($modules)->andWhere('t2.module')->in($modules)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll();
}
/**
* Get testtask linked cases.
*
* @param int $productID
* @param string $browseType
* @param int $queryID
* @param int $moduleID
* @param string $sort
* @param object $pager
* @param object $task
* @access public
* @return array
*/
public function getTaskCases($productID, $browseType, $queryID, $moduleID, $sort, $pager, $task)
{
/* Set modules and browse type. */
$modules = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
$browseType = ($browseType == 'bymodule' and $this->session->taskCaseBrowseType and $this->session->taskCaseBrowseType != 'bysearch') ? $this->session->taskCaseBrowseType : $browseType;
if($browseType == 'bymodule' or $browseType == 'all')
{
$runs = $this->getRuns($task->id, $modules, $sort, $pager);
}
elseif($browseType == 'assignedtome')
{
$runs = $this->getUserRuns($task->id, $this->session->user->account, $modules, $sort, $pager);
}
/* By search. */
elseif($browseType == 'bysearch')
{
if($this->session->testtaskQuery == false) $this->session->set('testtaskQuery', ' 1 = 1');
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set('testtaskQuery', $query->sql);
$this->session->set('testtaskForm', $query->form);
}
}
$queryProductID = $productID;
$allProduct = "`product` = 'all'";
$caseQuery = $this->session->testtaskQuery;
if(strpos($this->session->testtaskQuery, $allProduct) !== false)
{
$products = array_keys($this->loadModel('product')->getPrivProducts());
$caseQuery = str_replace($allProduct, '1', $this->session->testtaskQuery);
$caseQuery = $caseQuery . ' AND `product`' . helper::dbIN(array_keys($products));
$queryProductID = 'all';
}
$caseQuery = preg_replace('/`(\w+)`/', 't2.`$1`', $caseQuery);
$runs = $this->dao->select('t2.*,t1.*, t2.version as caseVersion')->from(TABLE_TESTRUN)->alias('t1')
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
->where($caseQuery)
->andWhere('t1.task')->eq($task->id)
->beginIF($task->branch)->andWhere('t2.branch')->in("0,{$task->branch}")->fi()
->orderBy(strpos($sort, 'assignedTo') !== false ? ('t1.' . $sort) : ('t2.' . $sort))
->page($pager)
->fetchAll();
}
return $runs;
}
/**
* Get info of a test run.
*

View File

@@ -3,14 +3,36 @@
<?php echo "<span class='prefix'>" . html::icon($lang->icons['usecase']) . '</span><strong>' . $task->name . '</strong>';?>
</div>
<div class='nav'>
<li>
<span>
<?php
echo isset($moduleID) ? $moduleName : $this->lang->tree->all;
if(!empty($moduleID))
{
$removeLink = $browseType == 'bymodule' ? inlink('cases', "taskID=$taskID&browseType=$browseType&param=0&orderBy=$orderBy&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("caseModule")';
echo '&nbsp;' . html::a($removeLink, "<i class='icon icon-remove'></i>") . '&nbsp;';
}
echo " <i class='icon-angle-right'></i>&nbsp; ";
?>
</span>
</li>
<?php
$hasCasesPriv = common::hasPriv('testtask', 'cases');
$hasGroupPriv = common::hasPriv('testtask', 'groupcase');
?>
<?php foreach($app->customMenu['featurebar'] as $type => $featurebar):?>
<?php if($featurebar['status'] == 'hide') continue;?>
<?php
if(common::hasPriv('testtask', 'cases') and ($type == 'all' or $type == 'assignedtome'))
if($hasCasesPriv and strpos($type, 'QUERY') === 0)
{
$queryID = (int)substr($type, 5);
echo "<li id='{$type}Tab'>" . html::a($this->inlink('cases', "taskID=$taskID&browseType=bySearch&param=$queryID"), $featurebar['link']) . "</li>";
}
elseif($hasCasesPriv and ($type == 'all' or $type == 'assignedtome'))
{
echo "<li id='{$type}Tab'>" . html::a($this->inlink('cases', "taskID=$taskID&browseType=$type&param=0"), $featurebar['link']) . "</li>";
}
elseif(common::hasPriv('testtask', 'cases') and $type == 'group')
elseif($hasGroupPriv and $type == 'group')
{
echo "<li id='groupTab' class='dropdown'>";
$groupBy = isset($groupBy) ? $groupBy : '';

View File

@@ -14,6 +14,7 @@
<?php include '../../common/view/datatable.fix.html.php';?>
<?php include './caseheader.html.php';?>
<?php js::set('confirmUnlink', $lang->testtask->confirmUnlinkCase)?>
<?php js::set('taskCaseBrowseType', ($browseType == 'bymodule' and $this->session->taskCaseBrowseType == 'bysearch') ? 'all' : $this->session->taskCaseBrowseType);?>
<script language="Javascript">
var browseType = '<?php echo $browseType;?>';
var moduleID = '<?php echo $moduleID;?>';
@@ -79,4 +80,17 @@ include $useDatatable ? dirname(__FILE__) . '/datatabledata.html.php' : dirname(
</table>
</form>
</div>
<script>
$('#module' + moduleID).addClass('active');
$('#' + taskCaseBrowseType + 'Tab').addClass('active');
<?php if($browseType == 'bysearch'):?>
$shortcut = $('#QUERY<?php echo (int)$param;?>Tab');
if($shortcut.size() > 0)
{
$shortcut.addClass('active');
$('#bysearchTab').removeClass('active');
$('#querybox').removeClass('show');
}
<?php endif;?>
</script>
<?php include '../../common/view/footer.html.php';?>