Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/cyy_bug
This commit is contained in:
@@ -53,7 +53,7 @@ class buildsEntry extends entry
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
if(!$project) return $this->send404();
|
||||
|
||||
$fields = 'execution,product,name,builder,date,scmPath,filePath,desc';
|
||||
$fields = 'execution,product,name,builder,date,scmPath,filePath,desc,branch';
|
||||
$this->batchSetPost($fields);
|
||||
|
||||
$control = $this->loadController('build', 'create');
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
35025 需求导入模板增加由谁评审字段
|
||||
旗舰版:
|
||||
35042 旗舰版周报3个工作项列表能显示总数
|
||||
修复的Bug
|
||||
27875 工时记录页面日期控件展开后显示遮挡
|
||||
27778 创建项目和编辑项目的所属项目集字段显示不一致
|
||||
27690 创建项目页面提示信息窗口建议向右展开
|
||||
27632 复制bug时希望可以同步反馈者和通知邮箱两个字段的信息
|
||||
27561 提需求页面所属产品右侧边框线缺失
|
||||
27547 编辑项目集预算,点击保存,提示有未提交表单
|
||||
|
||||
2022-09-08 17.6.1
|
||||
完成的需求
|
||||
|
||||
@@ -35,8 +35,15 @@
|
||||
</div>
|
||||
<?php else:?>
|
||||
<form id='myTaskForm' class="main-table table-task skip-iframe-modal" method="post">
|
||||
<?php $canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');?>
|
||||
<?php $canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');?>
|
||||
<?php
|
||||
$canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');
|
||||
$canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');
|
||||
$canFinish = common::hasPriv('task', 'finish');
|
||||
$canClose = common::hasPriv('task', 'close');
|
||||
$canRecordEstimate = common::hasPriv('task', 'recordEstimate');
|
||||
$canEdit = common::hasPriv('task', 'edit');
|
||||
$canBatchCreate = common::hasPriv('task', 'batchCreate');
|
||||
?>
|
||||
<table class="table has-sort-head table-fixed" id='taskTable'>
|
||||
<?php $vars = "mode=$mode&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
|
||||
<thead>
|
||||
@@ -134,10 +141,16 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
$canStart = ($task->status != 'pause' and common::hasPriv('task', 'start'));
|
||||
$canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart'));
|
||||
if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
|
||||
if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
|
||||
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
|
||||
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
|
||||
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
|
||||
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
|
||||
{
|
||||
echo "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true, '', '', $task->project);
|
||||
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'", '', $task->project);
|
||||
@@ -198,10 +211,17 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
$canStart = ($child->status != 'pause' and common::hasPriv('task', 'start'));
|
||||
$canRestart = ($child->status == 'pause' and common::hasPriv('task', 'restart'));
|
||||
if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
|
||||
if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
|
||||
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
|
||||
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
|
||||
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
|
||||
|
||||
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
|
||||
{
|
||||
echo "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true, '', '', $child->project);
|
||||
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', '', '', '', '', $child->project);
|
||||
|
||||
@@ -374,10 +374,10 @@ class actionModel extends model
|
||||
elseif($actionName == 'linked2execution' or $actionName == 'linked2kanban')
|
||||
{
|
||||
$execution = $this->dao->select('name,type')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch();
|
||||
$name = $execution->name;
|
||||
$method = $execution->type == 'kanban' ? 'kanban' : 'view';
|
||||
if($name)
|
||||
if(!empty($execution))
|
||||
{
|
||||
$name = $execution->name;
|
||||
$method = $execution->type == 'kanban' ? 'kanban' : 'view';
|
||||
$action->extra = (!common::hasPriv('execution', $method) or ($method == 'kanban' and isonlybody())) ? $name : html::a(helper::createLink('execution', $method, "executionID=$action->execution"), $name);
|
||||
}
|
||||
}
|
||||
@@ -1060,6 +1060,9 @@ class actionModel extends model
|
||||
|
||||
$programCondition = empty($this->app->user->view->programs) ? '0' : $this->app->user->view->programs;
|
||||
|
||||
$efforts = $this->dao->select('id')->from(TABLE_EFFORT)->where($condition)->fetchPairs();
|
||||
$efforts = !empty($efforts) ? implode(',', $efforts) : 0;
|
||||
|
||||
/* Get actions. */
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->where('objectType')->notIN($this->config->action->ignoreObjectType4Dynamic)
|
||||
@@ -1087,6 +1090,7 @@ class actionModel extends model
|
||||
/* Filter out client login/logout actions. */
|
||||
->andWhere('action')->notin('disconnectxuanxuan,reconnectxuanxuan,loginxuanxuan,logoutxuanxuan')
|
||||
->andWhere("IF((objectType = 'program'), (objectID in ($programCondition)), '1=1')")
|
||||
->andWhere("IF((objectType = 'effort'), (objectID in ($efforts)), '1=1')")
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
|
||||
@@ -17,7 +17,7 @@ foreach($products as $product)
|
||||
}
|
||||
$productsPinYin = common::convert2Pinyin($productNames);
|
||||
$linkHtml = $this->product->setParamsForLink($module, $link, $projectID, 0);
|
||||
$productsHtml = count($products) > 1 ? html::a($linkHtml, $this->lang->bug->allProduct, '', "class='text-important' title='{$this->lang->bug->allProduct}' data-key='" . zget($productsPinYin, $this->lang->bug->allProduct, '') . "' data-app='{$this->app->tab}'") : '';
|
||||
$productsHtml = count($products) > 1 ? html::a($linkHtml, $this->lang->bug->allProduct, '', "class='text-primary' title='{$this->lang->bug->allProduct}' data-key='" . zget($productsPinYin, $this->lang->bug->allProduct, '') . "' data-app='{$this->app->tab}'") : '';
|
||||
|
||||
foreach($products as $product)
|
||||
{
|
||||
@@ -26,7 +26,7 @@ foreach($products as $product)
|
||||
$productName .= $product->line ? zget($lines, $product->line, '') . '/' . $product->name : $product->name;
|
||||
$objectID = ($product->type != 'platform' && $module == 'branch' && $method == 'manage') ? $productID : $product->id;
|
||||
$linkHtml = $this->product->setParamsForLink($module, $link, $projectID, $product->id);
|
||||
$productsHtml .= html::a($linkHtml, $productName, '', "class='text-important $selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='{$this->app->tab}'");
|
||||
$productsHtml .= html::a($linkHtml, $productName, '', "class='text-primary $selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='{$this->app->tab}'");
|
||||
}
|
||||
?>
|
||||
<div class="table-row">
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#stories .action {display: none;}
|
||||
#bugs .action {display: none;}
|
||||
tbody tr td:first-child input {display: none;}
|
||||
.page-title .dropdown-menu {top: 40px; left: 70px;}
|
||||
</style>
|
||||
<?php endif;?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
@@ -28,8 +29,8 @@ tbody tr td:first-child input {display: none;}
|
||||
<?php common::printBack($browseLink, 'btn btn-secondary');?>
|
||||
<div class='divider'></div>
|
||||
<div class='page-title'>
|
||||
<span class='text' title='<?php echo $build->name;?>'>
|
||||
<?php echo html::a('javascript:void(0)', "<span class='label label-id'>{$build->id}</span> " . $build->name . " <span class='caret'></span>", '', "data-toggle='dropdown' class='btn btn-link btn-active-text'");?>
|
||||
<span title='<?php echo $build->name;?>'>
|
||||
<?php echo html::a('javascript:void(0)', "<span class='label label-id'>{$build->id}</span> " . $build->name . " <span class='caret'></span>", '', "data-toggle='dropdown' class='text btn btn-link btn-active-text'");?>
|
||||
<?php
|
||||
echo "<ul class='dropdown-menu'>";
|
||||
foreach($buildPairs as $id => $name)
|
||||
|
||||
@@ -25,7 +25,7 @@ foreach($products as $product)
|
||||
$linkHtml = sprintf($link, $product->id);
|
||||
if($product->status == 'normal' and $product->PO == $this->app->user->account)
|
||||
{
|
||||
$myProductsHtml .= html::a($linkHtml, $productName, '', "class='text-important $selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='$tab'");
|
||||
$myProductsHtml .= html::a($linkHtml, $productName, '', "class='text-primary $selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='$tab'");
|
||||
}
|
||||
else if($product->status == 'normal' and !($product->PO == $this->app->user->account))
|
||||
{
|
||||
|
||||
@@ -2498,7 +2498,7 @@ class execution extends control
|
||||
$kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, '', $orderBy);
|
||||
if(empty($kanbanGroup))
|
||||
{
|
||||
$this->kanban->createExecutionLane($executionID, $browseType, $groupBy);
|
||||
$this->kanban->createExecutionLane($executionID, $browseType);
|
||||
$kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, '', $orderBy);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,3 +11,4 @@ td.delayed {background: #e84e0f !important; color: white;}
|
||||
#taskList .c-progress{padding-right: 8px; text-align: right;}
|
||||
#datatable-taskList .c-progress{padding-right: 8px; text-align: right;}
|
||||
.c-finishedBy, .c-lastEditedBy {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
|
||||
#executionTaskForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
|
||||
|
||||
@@ -706,7 +706,7 @@ class executionModel extends model
|
||||
/* Check unique code for edited executions. */
|
||||
if($projectModel == 'scrum' and isset($executionCode) and empty($executionCode))
|
||||
{
|
||||
dao::$errors['code'][] = 'execution#' . $executionID . sprintf($this->lang->error->notempty, $this->lang->project->code);
|
||||
dao::$errors['code'][] = 'execution#' . $executionID . sprintf($this->lang->error->notempty, $this->lang->execution->execCode);
|
||||
return false;
|
||||
}
|
||||
elseif(!empty($executionCode))
|
||||
@@ -714,7 +714,7 @@ class executionModel extends model
|
||||
/* Check unique code for edited executions. */
|
||||
if(isset($codeList[$executionCode]))
|
||||
{
|
||||
dao::$errors['code'][] = 'execution#' . $executionID . sprintf($this->lang->error->unique, $this->lang->project->code, $executionCode);
|
||||
dao::$errors['code'][] = 'execution#' . $executionID . sprintf($this->lang->error->unique, $this->lang->execution->execCode, $executionCode);
|
||||
return false;
|
||||
}
|
||||
$codeList[$executionCode] = $executionCode;
|
||||
|
||||
@@ -1457,7 +1457,7 @@ $(function()
|
||||
resetRegionHeight($(this).hasClass('icon-angle-top') ? 'open' : 'close');
|
||||
});
|
||||
|
||||
$('.region-header').on('click', '.action', hideKanbanAction);
|
||||
$('#regionTabs, .region-header').on('click', '.action', hideKanbanAction);
|
||||
$('#TRAction').on('click', '.btn', hideKanbanAction);
|
||||
|
||||
/* Hide action box when user click document */
|
||||
|
||||
+15
-65
@@ -1554,7 +1554,7 @@ class kanbanModel extends model
|
||||
|
||||
$teamPairs = array();
|
||||
foreach($taskTeams[$taskID] as $account => $team) $teamPairs[$account] = $team->realname;
|
||||
$task->team = $teamPairs;
|
||||
$task->teamMember = $teamPairs;
|
||||
}
|
||||
|
||||
/* Get objects cards menus. */
|
||||
@@ -1610,6 +1610,7 @@ class kanbanModel extends model
|
||||
$laneData['order'] = $lane->order;
|
||||
$laneData['type'] = $browseType;
|
||||
$laneData['defaultCardType'] = $browseType;
|
||||
if(empty($laneID) and !in_array($groupBy, array('module', 'story', 'pri', 'severity'))) $laneID = '';
|
||||
|
||||
if($browseType == 'task' and $groupBy == 'story')
|
||||
{
|
||||
@@ -1675,8 +1676,9 @@ class kanbanModel extends model
|
||||
if($groupBy == 'assignedTo')
|
||||
{
|
||||
$laneID = (string)$laneID;
|
||||
if(empty($object->team) and $object->$groupBy !== $laneID) continue;
|
||||
if(!empty($object->team) and !in_array($laneID, array_keys($object->team), true)) continue;
|
||||
if(empty($object->$groupBy)) $object->$groupBy = '';
|
||||
if(empty($object->teamMember) and (string)$object->$groupBy !== $laneID) continue;
|
||||
if(!empty($object->teamMember) and !in_array($laneID, array_keys($object->teamMember), true)) continue;
|
||||
|
||||
if($object->$groupBy !== $laneID) $cardData['assignedTo'] = $laneID;
|
||||
}
|
||||
@@ -1745,9 +1747,9 @@ class kanbanModel extends model
|
||||
{
|
||||
if(!isset($groupByList[$item->$groupBy])) $groupByList[$item->$groupBy] = $item->$groupBy;
|
||||
|
||||
if($groupBy == 'assignedTo' and !empty($item->team))
|
||||
if($groupBy == 'assignedTo' and !empty($item->teamMember))
|
||||
{
|
||||
foreach($item->team as $account => $name)
|
||||
foreach($item->teamMember as $account => $name)
|
||||
{
|
||||
if(!isset($groupByList[$account])) $groupByList[$account] = $account;
|
||||
}
|
||||
@@ -1796,6 +1798,7 @@ class kanbanModel extends model
|
||||
|
||||
if(in_array($groupBy, array('module', 'story', 'pri', 'severity'))) $objectPairs[0] = $this->lang->$browseType->$groupBy . ': ' . $this->lang->kanban->noGroup;
|
||||
if(in_array($groupBy, array('assignedTo', 'source'))) $objectPairs[] = $this->lang->$browseType->$groupBy . ': ' . $this->lang->kanban->noGroup;
|
||||
if($browseType == 'bug' and $groupBy == 'type') $objectPairs[0] = $this->lang->$browseType->$groupBy . ': ' . $this->lang->kanban->noGroup;
|
||||
|
||||
$laneColor = 0;
|
||||
$order = 1;
|
||||
@@ -2420,72 +2423,19 @@ class kanbanModel extends model
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param string $type all|story|bug|task
|
||||
* @param string $groupBy default
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createExecutionLane($executionID, $type = 'all', $groupBy = 'default')
|
||||
public function createExecutionLane($executionID, $type = 'all')
|
||||
{
|
||||
if($groupBy == 'default' or $type == 'all')
|
||||
foreach($this->config->kanban->default as $type => $lane)
|
||||
{
|
||||
foreach($this->config->kanban->default as $type => $lane)
|
||||
{
|
||||
$lane->type = $type;
|
||||
$lane->execution = $executionID;
|
||||
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
|
||||
$lane->type = $type;
|
||||
$lane->execution = $executionID;
|
||||
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
|
||||
|
||||
$laneID = $this->dao->lastInsertId();
|
||||
$this->createExecutionColumns($laneID, $type, $executionID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->loadModel($type);
|
||||
$groupList = $this->getObjectGroup($executionID, $type, $groupBy);
|
||||
|
||||
$objectPairs = array();
|
||||
if($groupBy == 'module') $objectPairs = $this->dao->select('id,name')->from(TABLE_MODULE)->where('type')->in('story,bug,task')->andWhere('deleted')->eq('0')->fetchPairs();
|
||||
if($groupBy == 'story') $objectPairs = $this->dao->select('id,title')->from(TABLE_STORY)->where('deleted')->eq(0)->fetchPairs();
|
||||
if($groupBy == 'assignedTo') $objectPairs = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
$laneName = '';
|
||||
$laneOrder = 5;
|
||||
$colorIndex = 0;
|
||||
foreach($groupList as $groupKey)
|
||||
{
|
||||
if($groupKey)
|
||||
{
|
||||
if(strpos('module,story,assignedTo', $groupBy) !== false)
|
||||
{
|
||||
$laneName = zget($objectPairs, $groupKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
$laneName = zget($this->lang->$type->{$groupBy . 'List'}, $groupKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$laneName = $this->lang->kanban->noGroup;
|
||||
}
|
||||
|
||||
$lane = new stdClass();
|
||||
$lane->execution = $executionID;
|
||||
$lane->type = $type;
|
||||
$lane->groupby = $groupBy;
|
||||
$lane->extra = $groupKey;
|
||||
$lane->name = $laneName;
|
||||
$lane->color = $this->config->kanban->laneColorList[$colorIndex];
|
||||
$lane->order = $laneOrder;
|
||||
|
||||
$laneOrder += 5;
|
||||
$colorIndex += 1;
|
||||
if($colorIndex == count($this->config->kanban->laneColorList) + 1) $colorIndex = 0;
|
||||
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
|
||||
|
||||
$laneID = $this->dao->lastInsertId();
|
||||
$this->createExecutionColumns($laneID, $type, $executionID, $groupBy, $groupKey);
|
||||
}
|
||||
$laneID = $this->dao->lastInsertId();
|
||||
$this->createExecutionColumns($laneID, $type, $executionID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-11
@@ -809,17 +809,18 @@ EOF;
|
||||
}
|
||||
$PMList = $this->user->getListByAccounts($accounts, 'account');
|
||||
|
||||
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->project;
|
||||
$this->view->position[] = $this->lang->my->project;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->projects = $projects;
|
||||
$this->view->PMList = $PMList;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->status = $status;
|
||||
$this->view->recTotal = $recTotal;
|
||||
$this->view->recPerPage = $recPerPage;
|
||||
$this->view->pageID = $pageID;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->project;
|
||||
$this->view->position[] = $this->lang->my->project;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->projects = $projects;
|
||||
$this->view->PMList = $PMList;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->status = $status;
|
||||
$this->view->recTotal = $recTotal;
|
||||
$this->view->recPerPage = $recPerPage;
|
||||
$this->view->pageID = $pageID;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs('');
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,3 +36,4 @@ html[lang="en"] .c-user-short {width: 88px;}
|
||||
[lang^=fr] #taskTable .assigned-title {width: 130px !important;}
|
||||
[lang^=fr] #taskTable .c-user-short {width: 75px;}
|
||||
[lang^=fr] #taskTable .c-status {width: 71px;}
|
||||
#myTaskForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
|
||||
|
||||
@@ -60,9 +60,13 @@
|
||||
<td class='text-left'><?php echo $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end;?></td>
|
||||
<?php $projectBudget = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?>
|
||||
<td class='text-right c-budget'><?php echo $project->budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $lang->project->future;?></td>
|
||||
<td>
|
||||
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : ''?>
|
||||
<?php if(!empty($project->PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $project->PM), '', "data-toggle='modal' data-type='iframe' data-width='600'");?>
|
||||
<td class='c-manager'>
|
||||
<?php if(!empty($project->PM)):?>
|
||||
<?php $userName = zget($users, $project->PM);?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$project->PM], 'account' => $project->PM, 'name' => $userName), "avatar-circle avatar-top avatar-{$project->PM}"); ?>
|
||||
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : '';?>
|
||||
<?php echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");?>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class='c-actions'>
|
||||
<?php if($project->status == 'wait' || $project->status == 'suspended') common::printIcon('project', 'start', "projectID=$project->id", $project, 'list', 'play', '', 'iframe', true);?>
|
||||
|
||||
@@ -44,8 +44,15 @@
|
||||
</div>
|
||||
<?php else:?>
|
||||
<form id='myTaskForm' class="main-table table-task skip-iframe-modal" method="post">
|
||||
<?php $canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');?>
|
||||
<?php $canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');?>
|
||||
<?php
|
||||
$canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');
|
||||
$canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');
|
||||
$canFinish = common::hasPriv('task', 'finish');
|
||||
$canClose = common::hasPriv('task', 'close');
|
||||
$canRecordEstimate = common::hasPriv('task', 'recordEstimate');
|
||||
$canEdit = common::hasPriv('task', 'edit');
|
||||
$canBatchCreate = common::hasPriv('task', 'batchCreate');
|
||||
?>
|
||||
<div class="table-responsive">
|
||||
<table class="table has-sort-head table-fixed" id='taskTable'>
|
||||
<?php $vars = "mode=$mode&type=$type¶m=myQueryID&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
|
||||
@@ -151,11 +158,18 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
$attr = isset($kanbanList[$task->execution]) ? "disabled" : '';
|
||||
$attr = isset($kanbanList[$task->execution]) ? "disabled" : '';
|
||||
$canStart = ($task->status != 'pause' and common::hasPriv('task', 'start'));
|
||||
$canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart'));
|
||||
if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
|
||||
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
|
||||
{
|
||||
echo "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
|
||||
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'");
|
||||
@@ -221,10 +235,17 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
$canStart = ($child->status != 'pause' and common::hasPriv('task', 'start'));
|
||||
$canRestart = ($child->status == 'pause' and common::hasPriv('task', 'restart'));
|
||||
if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
|
||||
if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
|
||||
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
|
||||
|
||||
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
|
||||
{
|
||||
echo "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
|
||||
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, "data-width='95%'");
|
||||
|
||||
@@ -1286,6 +1286,9 @@ class product extends control
|
||||
$this->view->productStructure = $productStructure;
|
||||
$this->view->productLines = $productLines;
|
||||
$this->view->programLines = $programLines;
|
||||
$this->view->users = $this->user->getPairs('noletter');
|
||||
$this->view->userIdPairs = $this->user->getPairs('noletter|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs('');
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->pager = $pager;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#sidebar>.cell {width: 100%;}
|
||||
|
||||
th.c-name {width: 400px;}
|
||||
th.c-PO {width: 100px;}
|
||||
th.c-story {width: 290px;}
|
||||
th.c-bug {width: 150px;}
|
||||
th.c-plan {width: 45px;}
|
||||
@@ -89,4 +90,6 @@ th.c-actions {width: 50px;}
|
||||
#productTableList > tr.row-line.no-nest > td.text-left.table-nest-title > span.table-nest-icon.icon:before{content: '\e6f2'; background-color: white; display: inline;}
|
||||
.statistic {margin-left: 10px; color: #838a9d; float: left; position: relative; line-height: 28px;}
|
||||
.table-footer.fixed-footer .statistic {color: #fff;}
|
||||
#productTableList .c-manager {padding-left: 14px;}
|
||||
#productTableList .c-manager a {top: 7px; left: 22px;}
|
||||
.checkbox-primary {margin-right: 10px;}
|
||||
|
||||
@@ -1817,11 +1817,15 @@ class productModel extends model
|
||||
{
|
||||
$programKeys = array(0 => 0);
|
||||
foreach($products as $product) $programKeys[] = $product->program;
|
||||
$programs = $this->dao->select('id,name')->from(TABLE_PROGRAM)
|
||||
$programs = $this->dao->select('id,name,PM')->from(TABLE_PROGRAM)
|
||||
->where('id')->in(array_unique($programKeys))
|
||||
->fetchPairs();
|
||||
->fetchAll('id');
|
||||
|
||||
foreach($products as $product) $product->programName = isset($programs[$product->program]) ? $programs[$product->program] : '';
|
||||
foreach($products as $product)
|
||||
{
|
||||
$product->programName = isset($programs[$product->program]) ? $programs[$product->program]->name : '';
|
||||
$product->programPM = isset($programs[$product->program]) ? $programs[$product->program]->PM : '';
|
||||
}
|
||||
}
|
||||
|
||||
$stats = array();
|
||||
@@ -2045,6 +2049,7 @@ class productModel extends model
|
||||
/* Init vars. */
|
||||
/* Program name. */
|
||||
$productStructure[$product->program]['programName'] = $product->programName;
|
||||
$productStructure[$product->program]['programPM'] = $product->programPM;
|
||||
$productStructure[$product->program] = $this->statisticData('program', $productStructure, $product);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
<a class='table-nest-toggle table-nest-toggle-global' data-expand-text='<?php echo $lang->expand; ?>' data-collapse-text='<?php echo $lang->collapse; ?>'></a>
|
||||
<?php common::printOrderLink('name', $orderBy, $vars, $lang->product->name);?>
|
||||
</th>
|
||||
<th class='c-PO' rowspan="2">
|
||||
<?php common::printOrderLink('PO', $orderBy, $vars, $lang->product->manager);?>
|
||||
</th>
|
||||
<th class="c-story" colspan="5"><?php echo $lang->story->story;?></th>
|
||||
<th class="c-bug" colspan="2"><?php echo $lang->bug->common;?></th>
|
||||
<th class="c-plan" rowspan="2"><?php echo $lang->product->plan;?></th>
|
||||
@@ -103,6 +106,19 @@
|
||||
<span class="table-nest-icon icon table-nest-toggle"></span>
|
||||
<?php echo $program['programName']?>
|
||||
</td>
|
||||
<td class='c-manager'>
|
||||
<?php
|
||||
if(!empty($program['programPM']))
|
||||
{
|
||||
$programPM = $program['programPM'];
|
||||
$userName = zget($users, $programPM);
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$programPM], 'account' => $programPM, 'name' => $userName), 'avatar-circle avatar-top avatar-' . zget($userIdPairs, $programPM));
|
||||
|
||||
$userID = isset($userIdPairs[$programPM]) ? $userIdPairs[$programPM] : '';
|
||||
echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $program['draftStories'];?></td>
|
||||
<td><?php echo $program['activeStories'];?></td>
|
||||
<td><?php echo $program['changingStories'];?></td>
|
||||
@@ -142,6 +158,7 @@
|
||||
<span class="table-nest-icon icon table-nest-toggle"></span>
|
||||
<?php echo $line['lineName']?>
|
||||
</td>
|
||||
<td></td>
|
||||
<td><?php echo isset($line['draftStories']) ? $line['draftStories'] : 0;?></td>
|
||||
<td><?php echo isset($line['activeStories']) ? $line['activeStories'] : 0;?></td>
|
||||
<td><?php echo isset($line['changingStories']) ? $line['changingStories'] : 0;?></td>
|
||||
@@ -160,8 +177,7 @@
|
||||
<?php if(isset($line['products']) and is_array($line['products'])):?>
|
||||
<?php foreach($line['products'] as $productID => $product):?>
|
||||
<?php
|
||||
$totalStories = $product->stories['active'] + $product->stories['closed'] + $product->stories['draft'] + $product->stories['changing'] + $product->stories['reviewing'];
|
||||
$totalRequirements = $product->requirements['active'] + $product->requirements['closed'] + $product->requirements['draft'] + $product->requirements['changing'] + $product->requirements['reviewing'];
|
||||
$totalStories = $product->stories['active'] + $product->stories['closed'] + $product->stories['draft'] + $product->stories['changing'] + $product->stories['reviewing'];
|
||||
|
||||
$trClass = '';
|
||||
if($product->line)
|
||||
@@ -194,6 +210,18 @@
|
||||
echo html::a($this->createLink('product', 'browse', 'productID=' . $product->id), $product->name);
|
||||
?>
|
||||
</td>
|
||||
<td class='c-manager'>
|
||||
<?php
|
||||
if(!empty($product->PO))
|
||||
{
|
||||
$userName = zget($users, $product->PO);
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$product->PO], 'account' => $product->PO, 'name' => $userName), 'avatar-circle avatar-' . zget($userIdPairs, $product->PO));
|
||||
|
||||
$userID = isset($userIdPairs[$product->PO]) ? $userIdPairs[$product->PO] : '';
|
||||
echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $product->stories['draft'];?></td>
|
||||
<td><?php echo $product->stories['active'];?></td>
|
||||
<td><?php echo $product->stories['changing'];?></td>
|
||||
|
||||
@@ -49,11 +49,13 @@
|
||||
<?php else:?>
|
||||
<th><?php echo $lang->execution->name;?></th>
|
||||
<?php endif;?>
|
||||
<?php if(strpos('all,undone', $status) !== false):?>
|
||||
<th class='c-status'><?php echo $lang->project->status;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-user text-left'><?php echo $lang->project->PM;?></th>
|
||||
<th class="c-budget text-center"><?php echo $lang->project->budget;?></th>
|
||||
<th class='c-date'><?php echo $lang->project->begin;?></th>
|
||||
<th class='c-date'><?php echo $lang->project->end;?></th>
|
||||
<th class='c-status'><?php echo $lang->project->status;?></th>
|
||||
<th class="c-budget text-center"><?php echo $lang->project->budget;?></th>
|
||||
<th class="c-number text-right"><?php echo $lang->project->estimate;?></th>
|
||||
<th class="c-number text-right"><?php echo $lang->project->consume;?></th>
|
||||
<th class="c-progress"><?php echo $lang->project->progress;?></th>
|
||||
@@ -79,20 +81,22 @@
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<?php if(strpos('all,undone', $status) !== false):?>
|
||||
<?php $statusTitle = $this->processStatus('project', $project);?>
|
||||
<td class='c-status' title='<?php echo $statusTitle;?>'>
|
||||
<span class="status-project status-<?php echo $project->status?>"><?php echo $statusTitle;?></span>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<td class='padding-right'>
|
||||
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : ''?>
|
||||
<?php if(!empty($project->PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $project->PM), '', "data-toggle='modal' data-type='iframe' data-width='800'");?>
|
||||
</td>
|
||||
<td class='padding-right text-left'><?php echo $project->begin;?></td>
|
||||
<td class='padding-right text-left'><?php echo $project->end;?></td>
|
||||
<?php $status = $this->processStatus('project', $project);?>
|
||||
<td class='c-status' title='<?php echo $status;?>'>
|
||||
<span class="status-project status-<?php echo $project->status?>"><?php echo $status;?></span>
|
||||
</td>
|
||||
<?php $projectBudget = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?>
|
||||
<?php $budgetTitle = $project->budget != 0 ? zget($this->lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $this->lang->project->future;?>
|
||||
<?php $textStyle = $project->budget != 0 ? 'text-right' : 'text-center';?>
|
||||
<td title='<?php echo $budgetTitle;?>' class="text-ellipsis <?php echo $textStyle;?>"><?php echo $budgetTitle;?></td>
|
||||
<td class='padding-right text-left'><?php echo $project->begin;?></td>
|
||||
<td class='padding-right text-left'><?php echo $project->end;?></td>
|
||||
<td class="text-right" title="<?php echo $project->hours->totalEstimate . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalEstimate . $lang->execution->workHourUnit;?></td>
|
||||
<td class="text-right" title="<?php echo $project->hours->totalConsumed . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalConsumed . $lang->execution->workHourUnit;?></td>
|
||||
<td>
|
||||
|
||||
@@ -35,3 +35,7 @@ td.c-branch {overflow: hidden; text-align: left !important; text-overflow: ellip
|
||||
.panel-actions {position: relative; padding: 0 0; padding-top: 1px;}
|
||||
.icon-list {padding-left: 7px;}
|
||||
.icon-kanban {padding-left: 7px; font-size: 16px;}
|
||||
#productplanList .c-actions {width: 265px;}
|
||||
#productplanList .c-actions .btn+.btn {margin-left: -1px;}
|
||||
#productplanList .c-actions .btn {display: block; float: left;}
|
||||
#productplanList td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 6px 4px 0 0; float: left;}
|
||||
|
||||
@@ -1130,6 +1130,16 @@ class productplanModel extends model
|
||||
{
|
||||
$params = "planID=$plan->id";
|
||||
|
||||
$canStart = common::hasPriv('productplan', 'start');
|
||||
$canFinish = common::hasPriv('productplan', 'finish');
|
||||
$canClose = common::hasPriv('productplan', 'close');
|
||||
$canCreateExec = common::hasPriv('execution', 'create');
|
||||
$canLinkStory = common::hasPriv('productplan', 'linkStory');
|
||||
$canLinkBug = common::hasPriv('productplan', 'linkBug');
|
||||
$canEdit = common::hasPriv('productplan', 'edit');
|
||||
$canCreateChild = common::hasPriv('productplan', 'create');
|
||||
$canDelete = common::hasPriv('productplan', 'delete');
|
||||
|
||||
$menu = '';
|
||||
$menu .= $this->buildMenu('productplan', 'start', $params, $plan, $type, 'play', 'hiddenwin', '', false, '', $this->lang->productplan->startAB);
|
||||
$menu .= $this->buildMenu('productplan', 'finish', $params, $plan, $type, 'checked', 'hiddenwin', '', false, '', $this->lang->productplan->finishAB);
|
||||
@@ -1174,6 +1184,11 @@ class productplanModel extends model
|
||||
$menu .= "<button type='button' class='btn disabled'><i class='icon-plus' title='{$this->lang->productplan->createExecution}'></i></button>";
|
||||
}
|
||||
|
||||
if(($canStart or $canFinsh or $canClose or $canCreateExec) and ($canLinkStory or $canLinkBug or $canEdit or $canCreateChild or $canDelete))
|
||||
{
|
||||
$menu .= "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
if(common::hasPriv('productplan', 'linkStory', $plan) and $plan->parent >= 0)
|
||||
{
|
||||
$menu .= $this->buildMenu('productplan', 'view', "{$params}&type=story&orderBy=id_desc&link=true", $plan, $type, 'link', '', '', '', '', $this->lang->productplan->linkStory);
|
||||
@@ -1197,6 +1212,11 @@ class productplanModel extends model
|
||||
|
||||
$menu .= $this->buildMenu('productplan', 'create', "product={$plan->product}&branch={$plan->branch}&parent={$plan->id}", $plan, $type, 'split', '', '', '', '', $this->lang->productplan->children);
|
||||
|
||||
if(($canLinkStory or $canLinkBug or $canEdit or $canCreateChild) and $canDelete)
|
||||
{
|
||||
$menu .= "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
if($type == 'browse') $menu .= $this->buildMenu('productplan', 'delete', "{$params}&confirm=no", $plan, $type, 'trash', 'hiddenwin', '', '', $this->lang->productplan->delete);
|
||||
|
||||
if($type == 'view')
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<ul class='dropdown-menu' style='max-height:240px; max-width: 300px; overflow-y:auto'>
|
||||
<?php foreach($lang->productplan->orderList as $order => $label):?>
|
||||
<?php $active = $orderBy == $order ? 'active' : '';?>
|
||||
<li class='<?php echo $active;?>'><?php echo html::a(inlink('browse', "productID=$productID&branch=$branchID&browseType=$browseType&orderBy=$order"), $label);?></li>
|
||||
<li class='<?php echo $active;?>'><?php echo html::a(inlink('browse', "productID=$productID&branch=$branchID&browseType=$browseType&queryID=$queryID&orderBy=$order"), $label);?></li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
.c-actions {width: 250px;}
|
||||
#productplanList .c-actions .btn+.btn {margin-left: -1px;}
|
||||
#productplanList .c-actions .btn {display: block; float: left;}
|
||||
</style>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php common::sortFeatureMenu();?>
|
||||
|
||||
@@ -171,6 +171,8 @@ class program extends control
|
||||
$this->view->pager = $pager;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->products = $this->loadModel('product')->getStats($orderBy, $pager, $browseType, '', 'story', $programID);
|
||||
$this->view->userIdPairs = $this->user->getPairs('noletter|showid');
|
||||
$this->view->usersAvatar = $this->user->getAvatarPairs('');
|
||||
$this->view->showBatchEdit = $this->cookie->showProductBatchEdit;
|
||||
|
||||
$this->display();
|
||||
|
||||
@@ -3,4 +3,11 @@
|
||||
tbody.sortable > tr > td > span.sort-handler {color: #999;}
|
||||
.icon-move {color: #16a8f8;}
|
||||
.table.has-sort-head thead>tr>th>a:after, .table.has-sort-head thead>tr>th>a:before {top: -4px;}
|
||||
.c-PO {width: 100px;}
|
||||
.c-story {width: 300px;}
|
||||
.c-bug {width: 150px;}
|
||||
.c-plan, .c-release {width: 80px;}
|
||||
.c-actions {width: 70px;}
|
||||
#productList .c-manager {padding-left: 20px;}
|
||||
#productList .c-manager a {top: 7px; left: 26px;}
|
||||
.statistic {margin-left: 10px; color: #838a9d; float: left; position: relative; line-height: 28px;}
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
|
||||
.has-suffix > a {max-width: calc(100% - 100px); padding-right: 5px; color: #0c60e1; display: inline-block; max-width: calc(100% - 50px);}
|
||||
.c-budget {width:100px; text-align: right; padding-right:16px !important;}
|
||||
.c-manager {white-space: nowrap; overflow: hidden;}
|
||||
.c-manager a {top: 8px;}
|
||||
|
||||
@@ -73,10 +73,10 @@
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class='c-status'><span class="status-program status-<?php echo $program->status?>"><?php echo zget($lang->project->statusList, $program->status, '');?></span></td>
|
||||
<td>
|
||||
<td class="c-manager">
|
||||
<?php if(!empty($program->PM)):?>
|
||||
<?php $userName = zget($users, $program->PM);?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$program->PM], 'account' => $program->PM, 'name' => $userName), 'avatar-circle avatar-' . zget($userIdPairs, $program->PM)); ?>
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$program->PM], 'account' => $program->PM, 'name' => $userName), (($program->type == 'program' and $program->grade == 1 )? 'avatar-circle avatar-top avatar-' : 'avatar-circle avatar-') . zget($userIdPairs, $program->PM)); ?>
|
||||
<?php $userID = isset($PMList[$program->PM]) ? $PMList[$program->PM]->id : '';?>
|
||||
<?php echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");?>
|
||||
<?php endif;?>
|
||||
@@ -119,9 +119,8 @@
|
||||
#programTableList .icon-scrum:before {content: '\e9a2';}
|
||||
#programTableList .icon-waterfall:before {content: '\e9a4';}
|
||||
#programTableList .icon-kanban:before {content: '\e983';}
|
||||
/* #programTableList .has-nest-child > .c-name > a {color: #0b0f18!important;}
|
||||
#programTableList .is-nest-child > .c-name > a {color: #2463c7!important;} */
|
||||
#programTableList .c-name .label-danger {position: absolute; right: 10px; padding: 2px 4px;}
|
||||
#programTableList > tr[data-type="program"] > .c-name > a {color: #0b0f18 !important;}
|
||||
#programTableList > tr[data-type="program"] > .c-name:hover > a {color: #313c52 !important;}
|
||||
</style>
|
||||
<?php js::set('originOrders', $originOrders);?>
|
||||
<script>
|
||||
|
||||
@@ -51,11 +51,12 @@
|
||||
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
|
||||
</th>
|
||||
<th rowspan="2"><?php common::printOrderLink('name', $orderBy, $vars, $lang->product->name);?></th>
|
||||
<th class="w-300px" colspan="4"><?php echo $lang->story->story;?></th>
|
||||
<th class="w-150px" colspan="2"><?php echo $lang->bug->common;?></th>
|
||||
<th class="w-80px" rowspan="2"><?php echo $lang->product->plan;?></th>
|
||||
<th class="w-80px" rowspan="2"><?php echo $lang->product->release;?></th>
|
||||
<th class='c-actions w-70px' rowspan="2"><?php echo $lang->actions;?></th>
|
||||
<th class='c-PO' rowspan="2"><?php common::printOrderLink('PO', $orderBy, $vars, $lang->product->manager);?></th>
|
||||
<th class='c-story' colspan="4"><?php echo $lang->story->story;?></th>
|
||||
<th class='c-bug' colspan="2"><?php echo $lang->bug->common;?></th>
|
||||
<th class='c-plan' rowspan="2"><?php echo $lang->product->plan;?></th>
|
||||
<th class='c-release' rowspan="2"><?php echo $lang->product->release;?></th>
|
||||
<th class='c-actions' rowspan="2"><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
<tr class="text-center">
|
||||
<th style="border-left: 1px solid #ddd;"><?php echo $lang->story->draft;?></th>
|
||||
@@ -80,6 +81,18 @@
|
||||
<span class="product-id <?php if($canBatchEdit && $showBatchEdit) echo 'hidden';?>"><?php printf('%03d', $product->id);?></span>
|
||||
</td>
|
||||
<td class="c-name" title='<?php echo $product->name?>'><?php echo html::a($this->createLink('product', 'browse', 'product=' . $product->id), $product->name);?></td>
|
||||
<td class='c-manager'>
|
||||
<?php
|
||||
if(!empty($product->PO))
|
||||
{
|
||||
$userName = zget($users, $product->PO);
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$product->PO], 'account' => $product->PO, 'name' => $userName), 'avatar-circle avatar-' . zget($userIdPairs, $product->PO));
|
||||
|
||||
$userID = isset($userIdPairs[$product->PO]) ? $userIdPairs[$product->PO] : '';
|
||||
echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $product->stories['draft'];?></td>
|
||||
<td><?php echo $product->stories['active'];?></td>
|
||||
<td><?php echo $product->stories['changing'];?></td>
|
||||
|
||||
@@ -54,6 +54,7 @@ $canBatchEdit = common::hasPriv('project', 'batchEdit');
|
||||
foreach($setting as $value)
|
||||
{
|
||||
if($value->id == 'projectStatus' and $browseType !== 'all') $value->show = false;
|
||||
if($value->id == 'status' and strpos('all,unclosed', $browseType) === false) $value->show = false;
|
||||
if($value->show) $this->datatable->printHead($value, $orderBy, $vars, $canBatchEdit);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -33,7 +33,7 @@ $config->project->sortFields->budget = 'budget';
|
||||
|
||||
global $lang;
|
||||
$config->project->datatable = new stdclass();
|
||||
$config->project->datatable->defaultField = array('id', 'name', 'PM', 'status', 'begin', 'end', 'budget', 'progress', 'actions');
|
||||
$config->project->datatable->defaultField = array('id', 'name', 'status', 'PM', 'budget', 'begin', 'end', 'progress', 'actions');
|
||||
|
||||
$config->project->datatable->fieldList['id']['title'] = 'ID';
|
||||
$config->project->datatable->fieldList['id']['fixed'] = 'left';
|
||||
@@ -74,6 +74,12 @@ $config->project->datatable->fieldList['status']['required'] = 'no';
|
||||
$config->project->datatable->fieldList['status']['sort'] = 'yes';
|
||||
$config->project->datatable->fieldList['status']['pri'] = '2';
|
||||
|
||||
$config->project->datatable->fieldList['budget']['title'] = 'budget';
|
||||
$config->project->datatable->fieldList['budget']['fixed'] = 'no';
|
||||
$config->project->datatable->fieldList['budget']['width'] = '100';
|
||||
$config->project->datatable->fieldList['budget']['required'] = 'yes';
|
||||
$config->project->datatable->fieldList['budget']['pri'] = '3';
|
||||
|
||||
$config->project->datatable->fieldList['begin']['title'] = 'begin';
|
||||
$config->project->datatable->fieldList['begin']['fixed'] = 'no';
|
||||
$config->project->datatable->fieldList['begin']['width'] = '115';
|
||||
@@ -86,12 +92,6 @@ $config->project->datatable->fieldList['end']['width'] = '100';
|
||||
$config->project->datatable->fieldList['end']['required'] = 'no';
|
||||
$config->project->datatable->fieldList['end']['pri'] = '3';
|
||||
|
||||
$config->project->datatable->fieldList['budget']['title'] = 'budget';
|
||||
$config->project->datatable->fieldList['budget']['fixed'] = 'no';
|
||||
$config->project->datatable->fieldList['budget']['width'] = '100';
|
||||
$config->project->datatable->fieldList['budget']['required'] = 'yes';
|
||||
$config->project->datatable->fieldList['budget']['pri'] = '3';
|
||||
|
||||
$config->project->datatable->fieldList['teamCount']['title'] = 'teamCount';
|
||||
$config->project->datatable->fieldList['teamCount']['fixed'] = 'no';
|
||||
$config->project->datatable->fieldList['teamCount']['width'] = '70';
|
||||
|
||||
+15
-15
@@ -1125,7 +1125,6 @@ class project extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
$sort = common::appendOrder($orderBy);
|
||||
$bugs = $this->bug->getProjectBugs($projectID, $productID, $branchID, $build, $type, $param, $sort, '', $pager);
|
||||
|
||||
/* team member pairs. */
|
||||
$memberPairs = array();
|
||||
@@ -1154,20 +1153,6 @@ class project extends control
|
||||
}
|
||||
}
|
||||
|
||||
/* Process the openedBuild and resolvedBuild fields. */
|
||||
$bugs = $this->bug->processBuildForBugs($bugs);
|
||||
|
||||
/* Get story and task id list. */
|
||||
$storyIdList = $taskIdList = array();
|
||||
foreach($bugs as $bug)
|
||||
{
|
||||
if($bug->story) $storyIdList[$bug->story] = $bug->story;
|
||||
if($bug->task) $taskIdList[$bug->task] = $bug->task;
|
||||
if($bug->toTask) $taskIdList[$bug->toTask] = $bug->toTask;
|
||||
}
|
||||
$storyList = $storyIdList ? $this->loadModel('story')->getByList($storyIdList) : array();
|
||||
$taskList = $taskIdList ? $this->loadModel('task')->getByList($taskIdList) : array();
|
||||
|
||||
$moduleID = $type != 'bysearch' ? $param : 0;
|
||||
$modules = $this->tree->getAllModulePairs('bug');
|
||||
|
||||
@@ -1188,6 +1173,21 @@ class project extends control
|
||||
}
|
||||
$tree = $moduleID ? $this->tree->getByID($moduleID) : '';
|
||||
|
||||
/* Process the openedBuild and resolvedBuild fields. */
|
||||
$bugs = $this->bug->getProjectBugs($projectID, $productID, $branchID, $build, $type, $param, $sort, '', $pager);
|
||||
$bugs = $this->bug->processBuildForBugs($bugs);
|
||||
|
||||
/* Get story and task id list. */
|
||||
$storyIdList = $taskIdList = array();
|
||||
foreach($bugs as $bug)
|
||||
{
|
||||
if($bug->story) $storyIdList[$bug->story] = $bug->story;
|
||||
if($bug->task) $taskIdList[$bug->task] = $bug->task;
|
||||
if($bug->toTask) $taskIdList[$bug->toTask] = $bug->toTask;
|
||||
}
|
||||
$storyList = $storyIdList ? $this->loadModel('story')->getByList($storyIdList) : array();
|
||||
$taskList = $taskIdList ? $this->loadModel('task')->getByList($taskIdList) : array();
|
||||
|
||||
$showModule = !empty($this->config->datatable->projectBug->showModule) ? $this->config->datatable->projectBug->showModule : '';
|
||||
|
||||
/* Assign. */
|
||||
|
||||
@@ -1975,12 +1975,15 @@ class projectModel extends model
|
||||
$class .= ' c-name';
|
||||
$title = "title={$project->code}";
|
||||
}
|
||||
|
||||
if($id == 'name')
|
||||
elseif($id == 'name')
|
||||
{
|
||||
$class .= ' text-left';
|
||||
$title = "title='{$project->name}" . ($this->config->vision == 'lite' ? "'" : "({$this->lang->project->{$project->model}})'");
|
||||
}
|
||||
elseif($id == 'PM')
|
||||
{
|
||||
$class .= ' c-manager';
|
||||
}
|
||||
|
||||
if($id == 'end')
|
||||
{
|
||||
@@ -2029,10 +2032,12 @@ class projectModel extends model
|
||||
echo $project->code;
|
||||
break;
|
||||
case 'PM':
|
||||
$user = $this->loadModel('user')->getByID($project->PM, 'account');
|
||||
$userID = !empty($user) ? $user->id : '';
|
||||
$PMLink = helper::createLink('user', 'profile', "userID=$userID", '', true);
|
||||
$userName = zget($users, $project->PM);
|
||||
$user = $this->loadModel('user')->getByID($project->PM, 'account');
|
||||
$userID = !empty($user) ? $user->id : '';
|
||||
$userAvatar = !empty($user) ? $user->avatar : '';
|
||||
$PMLink = helper::createLink('user', 'profile', "userID=$userID", '', true);
|
||||
$userName = zget($users, $project->PM);
|
||||
if($project->PM) echo html::smallAvatar(array('avatar' => $userAvatar, 'account' => $project->PM, 'name' => $userName), "avatar-circle avatar-{$project->PM}");
|
||||
echo empty($project->PM) ? '' : html::a($PMLink, $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");
|
||||
break;
|
||||
case 'begin':
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
<?php
|
||||
foreach($setting as $value)
|
||||
{
|
||||
if($value->id == 'status' and strpos(',all,bysearch,', ",$browseType,") === false) $value->show = false;
|
||||
if($value->id == 'status' and strpos(',all,bysearch,undone,', ",$browseType,") === false) $value->show = false;
|
||||
if($value->id == 'teamCount' and $browseType == 'all') $value->show = false;
|
||||
if(commonModel::isTutorialMode() && ($value->id == 'PM' || $value->id == 'budget' || $value->id == 'teamCount')) $value->show = false;
|
||||
if($value->show) $this->datatable->printHead($value, $orderBy, $vars, $canBatchEdit);
|
||||
|
||||
@@ -81,7 +81,7 @@ class release extends control
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('view', "releaseID=$releaseID")));
|
||||
}
|
||||
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'notrunk|withbranch', 0, 'execution', false);
|
||||
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'notrunk|withbranch', 0, 'execution', '', false);
|
||||
$releasedBuilds = $this->release->getReleasedBuilds($productID, $branch);
|
||||
foreach($releasedBuilds as $build) unset($builds[$build]);
|
||||
unset($builds['trunk']);
|
||||
@@ -140,7 +140,7 @@ class release extends control
|
||||
$this->commonAction($release->product, $release->branch);
|
||||
$build = $this->build->getById($release->build);
|
||||
|
||||
$builds = $this->loadModel('build')->getBuildPairs($release->product, $release->branch, 'notrunk|withbranch', 0, 'execution', $release->build, false);
|
||||
$builds = $this->loadModel('build')->getBuildPairs($release->product, $release->branch, 'notrunk|withbranch', $release->project, 'project', $release->build, false);
|
||||
$releasedBuilds = $this->release->getReleasedBuilds($release->product, $release->branch);
|
||||
foreach($releasedBuilds as $releasedBuild)
|
||||
{
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<?php foreach($products as $product):?>
|
||||
<tr class="text-center">
|
||||
<?php $count = isset($product->plans) ? count($product->plans) : 1;?>
|
||||
<td class='text-left' title="<?php echo $product->name;?>" rowspan="<?php echo $count;?>"><?php echo "<p>" . html::a($this->createLink('product', 'view', "product=$product->id"), $product->name) . "</p>";?></td>
|
||||
<td class='c-name text-left' title="<?php echo $product->name;?>" rowspan="<?php echo $count;?>"><?php echo "<p>" . html::a($this->createLink('product', 'view', "product=$product->id"), $product->name) . "</p>";?></td>
|
||||
<td class='text-left' rowspan="<?php echo $count;?>"><?php echo "<p>" . zget($users, $product->PO) . '</p>';?></td>
|
||||
<?php if(isset($product->plans)):?>
|
||||
<?php $id = 1;?>
|
||||
|
||||
+21
-1
@@ -611,6 +611,26 @@ class task extends control
|
||||
if(!isset($this->view->members[$this->view->task->assignedTo])) $this->view->members[$this->view->task->assignedTo] = $this->view->task->assignedTo;
|
||||
if(isset($this->view->members['closed']) or $this->view->task->status == 'closed') $this->view->members['closed'] = 'Closed';
|
||||
|
||||
$executions = array();
|
||||
if(!empty($task->project))
|
||||
{
|
||||
$executionList = $this->execution->getPairs($task->project);
|
||||
$project = $this->loadModel('project')->getByID($task->project);
|
||||
|
||||
if(isset($project->model) and $project->model == 'waterfall')
|
||||
{
|
||||
foreach($executionList as $key=>$val)
|
||||
{
|
||||
$values = $project->name . '/' . $val;
|
||||
$executions[$key] = $values;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$executions = $executionList;
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->task->edit . 'TASK' . $this->lang->colon . $this->view->task->name;
|
||||
$this->view->position[] = $this->lang->task->common;
|
||||
$this->view->position[] = $this->lang->task->edit;
|
||||
@@ -619,7 +639,7 @@ class task extends control
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed', "{$this->view->task->openedBy},{$this->view->task->canceledBy},{$this->view->task->closedBy}");
|
||||
$this->view->showAllModule = isset($this->config->execution->task->allModule) ? $this->config->execution->task->allModule : '';
|
||||
$this->view->modules = $this->tree->getTaskOptionMenu($this->view->task->execution, 0, 0, $this->view->showAllModule ? 'allModule' : '');
|
||||
$this->view->executions = $this->config->systemMode == 'classic' ? $this->execution->getPairs() : $this->execution->getByProject($task->project, 'noclosed', 0, true, false, $task->execution);
|
||||
$this->view->executions = $this->config->systemMode == 'classic' ? $this->execution->getPairs() : $executions;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#linearefforts .nav li.active a{color: #0c64eb !important}
|
||||
.input-group-addon {background: #fff}
|
||||
.icon-calendar {color: rgb(22, 168, 248)}
|
||||
#recordForm .table>thead>tr>th{ border: none}
|
||||
#recordForm .table > thead > tr > th {border: none; font-weight: 400;}
|
||||
.main-header {border-bottom: none !important}
|
||||
.main-header ul.hours:before{content:"("}
|
||||
.main-header ul.hours:after{content:")"}
|
||||
|
||||
+15
-1
@@ -4140,10 +4140,24 @@ class taskModel extends model
|
||||
$storyChanged = !empty($task->storyStatus) && $task->storyStatus == 'active' && $task->latestStoryVersion > $task->storyVersion && !in_array($task->status, array('cancel', 'closed'));
|
||||
if($storyChanged) return $this->buildMenu('task', 'confirmStoryChange', $params, $task, 'browse', '', 'hiddenwin');
|
||||
|
||||
$canStart = ($task->status != 'pause' and common::hasPriv('task', 'start'));
|
||||
$canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart'));
|
||||
$canFinish = common::hasPriv('task', 'finish');
|
||||
$canClose = common::hasPriv('task', 'close');
|
||||
$canRecordEstimate = common::hasPriv('task', 'recordEstimate');
|
||||
$canEdit = common::hasPriv('task', 'edit');
|
||||
$canBatchCreate = ($this->config->vision == 'rnd' and common::hasPriv('task', 'batchCreate'));
|
||||
|
||||
if($task->status != 'pause') $menu .= $this->buildMenu('task', 'start', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
if($task->status == 'pause') $menu .= $this->buildMenu('task', 'restart', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
$menu .= $this->buildMenu('task', 'close', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
$menu .= $this->buildMenu('task', 'finish', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
$menu .= $this->buildMenu('task', 'close', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
|
||||
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
|
||||
{
|
||||
$menu .= "<div class='dividing-line'></div>";
|
||||
}
|
||||
|
||||
$menu .= $this->buildMenu('task', 'recordEstimate', $params, $task, 'browse', 'time', '', 'iframe', true);
|
||||
$menu .= $this->buildMenu('task', 'edit', $params, $task, 'browse');
|
||||
if($this->config->vision == 'rnd')
|
||||
|
||||
@@ -254,7 +254,7 @@ $lang->testcase->featureBar['browse']['all'] = $lang->testcase->allCases
|
||||
$lang->testcase->featureBar['browse']['wait'] = 'Wartend';
|
||||
$lang->testcase->featureBar['browse']['needconfirm'] = $lang->testcase->needConfirm;
|
||||
$lang->testcase->featureBar['browse']['group'] = 'Group View';
|
||||
$lang->testcase->featureBar['browse']['suite'] = 'Suite';
|
||||
$lang->testcase->featureBar['browse']['zerocase'] = 'Zero Case Story';
|
||||
$lang->testcase->featureBar['browse']['browseunits'] = 'Unit Test';
|
||||
$lang->testcase->featureBar['browse']['suite'] = 'Suite';
|
||||
$lang->testcase->featureBar['groupcase'] = $lang->testcase->featureBar['browse'];
|
||||
|
||||
@@ -254,7 +254,7 @@ $lang->testcase->featureBar['browse']['all'] = $lang->testcase->allCases
|
||||
$lang->testcase->featureBar['browse']['wait'] = 'Waiting';
|
||||
$lang->testcase->featureBar['browse']['needconfirm'] = $lang->testcase->needConfirm;
|
||||
$lang->testcase->featureBar['browse']['group'] = 'Group View';
|
||||
$lang->testcase->featureBar['browse']['suite'] = 'Suite';
|
||||
$lang->testcase->featureBar['browse']['zerocase'] = 'Zero Case Story';
|
||||
$lang->testcase->featureBar['browse']['browseunits'] = 'Unit Test';
|
||||
$lang->testcase->featureBar['browse']['suite'] = 'Suite';
|
||||
$lang->testcase->featureBar['groupcase'] = $lang->testcase->featureBar['browse'];
|
||||
|
||||
@@ -254,7 +254,7 @@ $lang->testcase->featureBar['browse']['all'] = $lang->testcase->allCases
|
||||
$lang->testcase->featureBar['browse']['wait'] = 'En Attente';
|
||||
$lang->testcase->featureBar['browse']['needconfirm'] = $lang->testcase->needConfirm;
|
||||
$lang->testcase->featureBar['browse']['group'] = 'Group View';
|
||||
$lang->testcase->featureBar['browse']['suite'] = 'Suite';
|
||||
$lang->testcase->featureBar['browse']['zerocase'] = 'Zero Case Story';
|
||||
$lang->testcase->featureBar['browse']['browseunits'] = 'Unit Test';
|
||||
$lang->testcase->featureBar['browse']['suite'] = 'Suite';
|
||||
$lang->testcase->featureBar['groupcase'] = $lang->testcase->featureBar['browse'];
|
||||
|
||||
@@ -254,7 +254,7 @@ $lang->testcase->featureBar['browse']['all'] = '全部';
|
||||
$lang->testcase->featureBar['browse']['wait'] = '待评审';
|
||||
$lang->testcase->featureBar['browse']['needconfirm'] = $lang->testcase->needConfirm;
|
||||
$lang->testcase->featureBar['browse']['group'] = '分组查看';
|
||||
$lang->testcase->featureBar['browse']['suite'] = '套件';
|
||||
$lang->testcase->featureBar['browse']['zerocase'] = "零用例{$lang->SRCommon}";
|
||||
$lang->testcase->featureBar['browse']['browseunits'] = '单元测试';
|
||||
$lang->testcase->featureBar['browse']['suite'] = '套件';
|
||||
$lang->testcase->featureBar['groupcase'] = $lang->testcase->featureBar['browse'];
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
.btn-group a.btn-primary {border-right: 1px solid rgba(255,255,255,0.2);}
|
||||
.btn-group button.dropdown-toggle.btn-primary {padding:6px;}
|
||||
.body-modal #mainMenu>.btn-toolbar {width: auto;}
|
||||
#mainMenu .dividing-line {width: 1px; height: 16px; display: inline-block; background: #D8DBDE; margin: 7px 8px 0 0; float: left;}
|
||||
</style>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<?php if(!($this->app->rawMethod == 'groupcase')):?>
|
||||
@@ -195,3 +196,50 @@ if(!empty($headerHooks))
|
||||
foreach($headerHooks as $fileName) include($fileName);
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
var $allTab = $('#allTab');
|
||||
var $waitTab = $('#waitTab');
|
||||
var $needconfirmTab = $('#needconfirmTab');
|
||||
var $groupTab = $('#groupTab');
|
||||
var $zerocaseTab = $('#zerocaseTab');
|
||||
var $bysuiteTab = $('#bysuiteTab');
|
||||
var $browseunitsTab = $('#browseunitsTab');
|
||||
var hasAllTab = $allTab.length > 0;
|
||||
var hasWaitTab = $waitTab.length > 0;
|
||||
var hasNeedconfirmTab = $needconfirmTab.length > 0;
|
||||
var hasGroupTab = $groupTab.length > 0;
|
||||
var hasZerocaseTab = $zerocaseTab.length > 0;
|
||||
var hasbysuiteTab = $bysuiteTab.length > 0;
|
||||
var hasBrowseunitsTab = $browseunitsTab.length > 0;
|
||||
|
||||
if((hasAllTab || hasWaitTab) && (hasNeedconfirmTab || hasGroupTab || hasbysuiteTab || hasZerocaseTab || hasBrowseunitsTab))
|
||||
{
|
||||
if(hasWaitTab)
|
||||
{
|
||||
$waitTab.after("<div class='dividing-line'></div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
$allTab.after("<div class='dividing-line'></div>");
|
||||
}
|
||||
}
|
||||
|
||||
if((hasNeedconfirmTab || hasGroupTab || hasZerocaseTab) && (hasbysuiteTab || hasBrowseunitsTab))
|
||||
{
|
||||
if(hasZerocaseTab)
|
||||
{
|
||||
$zerocaseTab.after("<div class='dividing-line'></div>");
|
||||
}
|
||||
else if(hasGroupTab)
|
||||
{
|
||||
$groupTab.after("<div class='dividing-line'></div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
$needconfirmTab.after("<div class='dividing-line'></div>");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php if(!isonlybody()):?>
|
||||
<?php echo html::a($browseLink, '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary' data-app={$this->app->tab}");?>
|
||||
<?php echo html::a($browseLink, '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary'");?>
|
||||
<div class="divider"></div>
|
||||
<?php endif;?>
|
||||
<div class="page-title">
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -122,3 +122,12 @@ body.xxc-embed.m-productplan-view,body.xxc-embed.m-bug-browse,body.xxc-embed.m-p
|
||||
#mainMenu > .btn-toolbar .btn-link .label-light {color: #203362; background: #fff;}
|
||||
#mainMenu > .btn-toolBar .btn-active-text,
|
||||
#mainMenu > .btn-toolbar .btn-active-text {background: #E6EAF1;} */
|
||||
|
||||
#programTableList > tr:hover {background: #E6F0FF; opacity: 0.8;}
|
||||
#programTableList > tr[data-type="project"] > .c-name:hover > a {color: #1E6AEB !important;}
|
||||
#programTableList > tr[data-type="project"] > .c-name > a {color: #2463c7 !important;}
|
||||
#mainMenu > div.btn-toolbar.pull-right > a.btn.btn-link.iframe {color: #18A6FD;}
|
||||
|
||||
#projectForm .c-name .label-danger,
|
||||
#executionTableList .c-name .label-danger,
|
||||
#programTableList .c-name .label-danger {position: absolute; right: 10px; padding: 2px 4px;}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,7 +26,7 @@ $(function()
|
||||
const mainHeader = document.getElementById('mainHeader');
|
||||
if(!mainHeader) return;
|
||||
const style = window.getComputedStyle(mainHeader, null);
|
||||
const color = window.getComputedStyle(document.querySelector('#navbar .nav>li:not(.active)>a'), null).color;
|
||||
const color = window.getComputedStyle(document.querySelector('#navbar .nav>li:not(.active)>a, #userMenu .nav>li:not(.active)>a'), null).color;
|
||||
const clientHeaderStyle = {windowControlBtnColor: color, background: style.background, color: color};
|
||||
window.parent.appHeaderStyleUpdated = true;
|
||||
window.open('xxc://setAppHeaderStyle/zentao-integrated/' + encodeURIComponent(JSON.stringify(clientHeaderStyle)), '_blank');
|
||||
|
||||
@@ -150,7 +150,7 @@ class xuanxuanMessage extends messageModel
|
||||
|
||||
$content = json_encode($contentData);
|
||||
$avatarUrl = $server . $this->app->getWebRoot() . 'favicon.ico';
|
||||
if($target) $this->loadModel('im')->messageCreateNotify($target, $title, $subtitle = '', $content, $contentType = 'object', $url, $actions = array(), $sender = array('id' => 'zentao', 'realname' => $this->lang->message->sender, 'name' => $this->lang->message->sender, 'avatar' => $avatarUrl));
|
||||
if($target && ($objectType == 'bug' || $objectType == 'task' || $objectType == 'story')) $this->loadModel('im')->messageCreateNotify($target, $title, $subtitle = '', $content, $contentType = 'object', $url, $actions = array(), $sender = array('id' => 'zentao', 'realname' => $this->lang->message->sender, 'name' => $this->lang->message->sender, 'avatar' => $avatarUrl));
|
||||
|
||||
if($objectType == 'mr' and is_array($this->lang->message->mr->$actionType) and !empty($object->assignee))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user