Merge branch 'master' into 'liyuchun_59437'

# Conflicts:
#   module/repo/control.php
This commit is contained in:
孙广明
2022-07-05 09:20:43 +00:00
145 changed files with 2133 additions and 411 deletions
+1 -1
View File
@@ -195,7 +195,7 @@ class userEntry extends Entry
if(!common::hasPriv('my', 'work')) break;
$control = $this->loadController('my', 'task');
$control->task($this->param('type', 'assignedTo'), $this->param('order', 'id_desc'), $this->param('total', 0), $this->param('limit', 5), $this->param('page', 1));
$control->task($this->param('type', 'assignedTo'), 0, $this->param('order', 'id_desc'), $this->param('total', 0), $this->param('limit', 5), $this->param('page', 1));
$data = $this->getData();
if($data->status == 'success')
+1
View File
@@ -270,6 +270,7 @@ define('TABLE_PROJECTCASE', '`' . $config->db->prefix . 'projectcase`');
define('TABLE_TASKESTIMATE', '`' . $config->db->prefix . 'taskestimate`');
define('TABLE_EFFORT', '`' . $config->db->prefix . 'effort`');
define('TABLE_BURN', '`' . $config->db->prefix . 'burn`');
define('TABLE_CFD', '`' . $config->db->prefix . 'cfd`');
define('TABLE_BUILD', '`' . $config->db->prefix . 'build`');
define('TABLE_ACL', '`' . $config->db->prefix . 'acl`');
+9
View File
@@ -0,0 +1,9 @@
CREATE TABLE `zt_cfd` (
`id` int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`execution` int(8) NOT NULL,
`type` char(30) NOT NULL,
`name` char(30) NOT NULL,
`count` smallint NOT NULL,
`date` date NOT NULL,
UNIQUE KEY `execution_type_name_date` (`execution`,`type`,`name`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+10
View File
@@ -411,6 +411,16 @@ CREATE TABLE IF NOT EXISTS `zt_casestep` (
KEY `case` (`case`),
KEY `version` (`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_cfd`;
CREATE TABLE `zt_cfd` (
`id` int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`execution` int(8) NOT NULL,
`type` char(30) NOT NULL,
`name` char(30) NOT NULL,
`count` smallint NOT NULL,
`date` date NOT NULL,
UNIQUE KEY `execution_type_name_date` (`execution`,`type`,`name`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_company`;
CREATE TABLE IF NOT EXISTS `zt_company` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
@@ -1,3 +1,3 @@
<script>
$('#assigntomeBlock>ul>li>a:not([href$="todo"]):not([href$="task"])').parent().remove();
$('#assigntomeBlock>ul>li>a:not([href$="todo"]):not([href$="task"]:not[href$="feedback"])').parent().remove();
</script>
@@ -1,3 +1,8 @@
<script>
$("#createCaseActionMenu a[href=#toBug]").remove();
$("#createCaseActionMenu").parent('.btn-group').remove();
$("#actionbox .histories-list li").each(function()
{
var text = $(this).find('a').text();
$(this).find('a').parent().text(text);
});
</script>
@@ -17,6 +17,7 @@ body {margin-bottom: 25px;}
#mainMenu .btn-toolbar .btn-group .dropdown-menu .btn-active-text:hover .text {color: #fff;}
#mainMenu .btn-toolbar .btn-group .dropdown-menu .btn-active-text:hover .text:after {border-bottom: unset;}
.body-modal #mainMenu>.btn-toolbar {width: auto;}
.assignedTo{border-radius: 4px !important;}
</style>
<?php js::set('browseType', $browseType);?>
<?php js::set('productID', $productID);?>
@@ -411,7 +412,7 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
<?php if($canBatchAssignTo):?>
<div class="btn-group dropup">
<button data-toggle="dropdown" type="button" class="btn"><?php echo $lang->story->assignedTo;?> <span class="caret"></span></button>
<button data-toggle="dropdown" type="button" class="btn assignedTo"><?php echo $lang->story->assignedTo;?> <span class="caret"></span></button>
<?php
$withSearch = count($users) > 10;
$actionLink = $this->createLink('story', 'batchAssignTo', "productID=$productID");
@@ -0,0 +1,3 @@
<script>
if(config.onlybody == 'yes') $('#storyList .c-title').width(110);
</script>
@@ -46,7 +46,7 @@
<th class='c-spec<?php echo zget($visibleFields, 'spec', ' hidden') . zget($requiredFields, 'spec', '', ' required');?>'><?php echo $lang->story->spec;?></th>
<th class='c-pri<?php echo zget($requiredFields, 'pri', '', ' required');?>'><?php echo $lang->story->pri;?></th>
<th class='c-estimate<?php echo zget($requiredFields, 'estimate', '', ' required');?>'><?php echo $lang->story->estimate;?></th>
<th style="width: 200px !important"><?php echo $lang->story->reviewedBy;?></th>
<th class="<?php if($forceReview) echo ' required'?>" style="width: 200px !important"><?php echo $lang->story->reviewedBy;?></th>
<th class='c-keywords<?php echo zget($requiredFields, 'keywords', '', ' required');?>'><?php echo $lang->story->keywords;?></th>
<?php
$extendFields = $this->story->getFlowExtendFields();
+1 -1
View File
@@ -99,7 +99,7 @@
<tr>
<th><?php echo $lang->task->story;?></th>
<td colspan='3'>
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('story', 'create', "productID=$productID&branch=0&moduleID=0&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=story"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('story', 'create', "productID=$productID&branch=0&moduleID=0&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=story&_single"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
<div class='input-group <?php if(empty($stories)) echo "hidden";?>'>
<?php echo html::select('story', $stories, $task->story, "class='form-control chosen' onchange='setStoryRelated();'");?>
<span class='input-group-btn' id='preview'><a href='#' class='btn iframe'><?php echo $lang->preview;?></a></span>
@@ -20,6 +20,7 @@
.hide-sidebar #sidebar > .cell {display: none;}
.hide-sidebar #sidebar > .sidebar-toggle > .icon:before {content: "\e314";}
#date {float: left; margin-right: 10px; margin-left: 0px;}
.cell .nav>li>a:focus {background-color: unset;}
</style>
<?php js::set('moreLang', $this->lang->side->more);?>
<?php js::set('moduleList', $config->todo->moduleList);?>
@@ -0,0 +1,2 @@
<?php
$this->config->workflowdatasource->excludeDatasource = 'litefeedbackStatus,litefeedbackModules,litefeedbackType,litefeedbackSolution,litefeedbackclosedReason';
@@ -0,0 +1,19 @@
<?php
/**
* Get datasource list.
*
* @param string $orderBy
* @param objcet $pager
* @access public
* @return array
*/
public function getList($orderBy = 'id_desc', $pager = null)
{
return $this->dao->select('*')->from(TABLE_WORKFLOWDATASOURCE)
->where(1)
->beginIF(!empty($this->config->vision))->andWhere('vision')->eq($this->config->vision)->fi()
->beginIF($this->config->visions == ',lite,')->andWhere('code')->notin($this->config->workflowdatasource->excludeDatasource)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll();
}
+20 -2
View File
@@ -1717,6 +1717,7 @@ class block extends control
if(common::hasPriv('risk', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['risk'] = true;
if(common::hasPriv('issue', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['issue'] = true;
if(common::hasPriv('meeting', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['meeting'] = true;
if(common::hasPriv('feedback', 'view') and in_array($this->config->edition, array('max', 'biz'))) $hasViewPriv['feedback'] = true;
$params = $this->get->param;
$params = json_decode(base64_decode($params));
@@ -1725,8 +1726,14 @@ class block extends control
$objectCountList = array('todo' => 'todoCount', 'task' => 'taskCount', 'bug' => 'bugCount', 'story' => 'storyCount', 'requirement' => 'requirementCount');
if($this->config->edition == 'max')
{
$objectList += array('risk' => 'risks', 'issue' => 'issues');
$objectCountList += array('risk' => 'riskCount', 'issue' => 'issueCount');
$objectList += array('risk' => 'risks', 'issue' => 'issues', 'feedback' => 'feedbacks');
$objectCountList += array('risk' => 'riskCount', 'issue' => 'issueCount', 'feedback' => 'feedbackCount');
}
if($this->config->edition == 'biz')
{
$objectList += array('feedback' => 'feedbacks');
$objectCountList += array('feedback' => 'feedbackCount');
}
$tasks = $this->loadModel('task')->getUserSuspendedTasks($this->app->user->account);
@@ -1749,6 +1756,10 @@ class block extends control
->beginIF($objectType == 'story' or $objectType == 'requirement')->andWhere('t2.deleted')->eq('0')->fi()
->beginIF($objectType == 'todo')->andWhere('t1.cycle')->eq(0)->andWhere('t1.status')->eq('wait')->andWhere('t1.vision')->eq($this->config->vision)->fi()
->beginIF($objectType != 'todo')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($objectType == 'feedback')
->andWhere('t1.status')->in('wait, noreview')
->andWhere('t1.assignedTo')->eq($this->app->user->account)
->fi()
->orderBy($orderBy)
->beginIF($limitCount)->limit($limitCount)->fi()
->fetchAll();
@@ -1787,6 +1798,13 @@ class block extends control
if($objectType == 'risk') $this->app->loadLang('risk');
if($objectType == 'issue') $this->app->loadLang('issue');
if($objectType == 'feedback')
{
$this->app->loadLang('feedback');
$this->view->users = $this->loadModel('user')->getPairs('all,noletter');
$this->view->products = $this->loadModel('product')->getPairs();
}
$count[$objectType] = count($objects);
$this->view->{$objectList[$objectType]} = $objects;
}
+9 -7
View File
@@ -357,6 +357,7 @@ $lang->block->availableBlocks->testtask = 'Testaufgaben';
$lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -469,13 +470,14 @@ $lang->block->orderByList->story['status_desc'] = 'Status Absteigend';
$lang->block->orderByList->story['stage_asc'] = 'Phase Aufsteigend';
$lang->block->orderByList->story['stage_desc'] = 'Phase Absteigend';
$lang->block->todoCount = 'Todos';
$lang->block->taskCount = 'Aufgaben';
$lang->block->bugCount = 'Bugs';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->todoCount = 'Todos';
$lang->block->taskCount = 'Aufgaben';
$lang->block->bugCount = 'Bugs';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->typeList = new stdclass();
+9 -7
View File
@@ -357,6 +357,7 @@ $lang->block->availableBlocks->testtask = 'Requests';
$lang->block->availableBlocks->risk = 'Risks';
$lang->block->availableBlocks->issue = 'Issues';
$lang->block->availableBlocks->meeting = 'Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -469,13 +470,14 @@ $lang->block->orderByList->story['status_desc'] = 'Story Status DESC';
$lang->block->orderByList->story['stage_asc'] = 'Story Phase ASC';
$lang->block->orderByList->story['stage_desc'] = 'Story Phase DESC';
$lang->block->todoCount = 'Todo';
$lang->block->taskCount = 'Task';
$lang->block->bugCount = 'Bug';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->todoCount = 'Todo';
$lang->block->taskCount = 'Task';
$lang->block->bugCount = 'Bug';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->typeList = new stdclass();
+9 -7
View File
@@ -357,6 +357,7 @@ $lang->block->availableBlocks->testtask = 'Recettes';
$lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -469,13 +470,14 @@ $lang->block->orderByList->story['status_desc'] = 'Tri par Statut Story DESC';
$lang->block->orderByList->story['stage_asc'] = 'Tri par Phase Story ASC';
$lang->block->orderByList->story['stage_desc'] = 'Tri par Phase Story DESC';
$lang->block->todoCount = 'Todo';
$lang->block->taskCount = 'Task';
$lang->block->bugCount = 'Bug';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->todoCount = 'Todo';
$lang->block->taskCount = 'Task';
$lang->block->bugCount = 'Bug';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->typeList = new stdclass();
+9 -7
View File
@@ -319,6 +319,7 @@ $lang->block->availableBlocks->testtask = 'Yêu cầu';
$lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = 'Project';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -431,13 +432,14 @@ $lang->block->orderByList->story['status_desc'] = 'Tình trạng câu chuyện g
$lang->block->orderByList->story['stage_asc'] = 'Giai đoạn câu chuyện tăng dần';
$lang->block->orderByList->story['stage_desc'] = 'Giai đoạn câu chuyện giảm dần';
$lang->block->todoCount = 'Việc làm';
$lang->block->taskCount = 'Nhiệm vụ';
$lang->block->bugCount = 'Bug';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->todoCount = 'Việc làm';
$lang->block->taskCount = 'Nhiệm vụ';
$lang->block->bugCount = 'Bug';
$lang->block->riskCount = 'Risk';
$lang->block->issueCount = 'Issues';
$lang->block->storyCount = 'Stories';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->typeList = new stdclass();
+9 -7
View File
@@ -357,6 +357,7 @@ $lang->block->availableBlocks->testtask = '测试版本列表';
$lang->block->availableBlocks->risk = '风险';
$lang->block->availableBlocks->issue = '问题';
$lang->block->availableBlocks->meeting = '会议';
$lang->block->availableBlocks->feedback = '反馈';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = '项目';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -469,13 +470,14 @@ $lang->block->orderByList->story['status_desc'] = '状态倒序';
$lang->block->orderByList->story['stage_asc'] = '阶段正序';
$lang->block->orderByList->story['stage_desc'] = '阶段倒序';
$lang->block->todoCount = '待办数';
$lang->block->taskCount = '任务数';
$lang->block->bugCount = 'Bug数';
$lang->block->riskCount = '风险数';
$lang->block->issueCount = '问题数';
$lang->block->storyCount = '需求数';
$lang->block->meetingCount = '会议数';
$lang->block->todoCount = '待办数';
$lang->block->taskCount = '任务数';
$lang->block->bugCount = 'Bug数';
$lang->block->riskCount = '风险数';
$lang->block->issueCount = '问题数';
$lang->block->storyCount = '需求数';
$lang->block->meetingCount = '会议数';
$lang->block->feedbackCount = '反馈数';
$lang->block->typeList = new stdclass();
+9 -7
View File
@@ -332,6 +332,7 @@ $lang->block->availableBlocks->testtask = '測試版本列表';
$lang->block->availableBlocks->risk = '我的風險';
$lang->block->availableBlocks->issue = '我的問題';
$lang->block->availableBlocks->meeting = '我的會議';
$lang->block->availableBlocks->feedback = '我的反饋';
if($config->systemMode == 'new') $lang->block->moduleList['project'] = '項目';
$lang->block->moduleList['product'] = $lang->productCommon;
@@ -444,13 +445,14 @@ $lang->block->orderByList->story['status_desc'] = '狀態倒序';
$lang->block->orderByList->story['stage_asc'] = '階段正序';
$lang->block->orderByList->story['stage_desc'] = '階段倒序';
$lang->block->todoCount = '待辦數';
$lang->block->taskCount = '任務數';
$lang->block->bugCount = 'Bug數';
$lang->block->riskCount = '風險數';
$lang->block->issueCount = '問題數';
$lang->block->storyCount = '需求數';
$lang->block->meetingCount = '會議數';
$lang->block->todoCount = '待辦數';
$lang->block->taskCount = '任務數';
$lang->block->bugCount = 'Bug數';
$lang->block->riskCount = '風險數';
$lang->block->issueCount = '問題數';
$lang->block->storyCount = '需求數';
$lang->block->meetingCount = '會議數';
$lang->block->feedbackCount = '反饋數';
$lang->block->typeList = new stdclass();
+4
View File
@@ -776,6 +776,10 @@ class blockModel extends model
$params->meetingCount['name'] = $this->lang->block->meetingCount;
$params->meetingCount['default'] = 20;
$params->meetingCount['control'] = 'input';
$params->feedbackCount['name'] = $this->lang->block->feedbackCount;
$params->feedbackCount['default'] = 20;
$params->feedbackCount['control'] = 'input';
}
$params->storyCount['name'] = $this->lang->block->storyCount;
+36
View File
@@ -0,0 +1,36 @@
<?php if(empty($feedbacks)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-feedbacks .c-id {width: 50px;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-fixed table-fixed-head table-hover tablesorter block-feedbacks <?php if(!$longBlock) echo 'block-sm'?>'>
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB?></th>
<th class='c-product'><?php echo $lang->feedback->product;?></th>
<th class='c-title'><?php echo $lang->feedback->title?></th>
<th class='c-type'><?php echo $lang->feedback->type;?></th>
<th class='c-openedBy'><?php echo $lang->feedback->openedBy;?></th>
<th class='c-openedDate'><?php echo $lang->feedback->openedDate;?></th>
</tr>
</thead>
<tbody>
<?php foreach($feedbacks as $feedback):?>
<?php
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : '';
?>
<tr>
<td><?php echo sprintf('%03d', $feedback->id);?></td>
<td><?php echo zget($products, $feedback->product);?></td>
<td class='c-title' title='<?php echo $feedback->title?>'><?php echo html::a($this->createLink('feedback', 'view', "feedbackID=$feedback->id"), $feedback->title, '', "data-app='my'")?></td>
<td><?php echo zget($lang->feedback->typeList, $feedback->type)?></td>
<td><?php echo zget($users, $feedback->openedBy)?></td>
<td><?php echo $feedback->openedDate;?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
@@ -127,10 +127,10 @@ $(function()
<div class="tile-title"><?php echo $lang->SRCommon;?></div>
<?php if($product->stories):?>
<div class="tile-amount"><?php echo array_sum($product->stories);?></div>
<?php common::printLink('product', 'browse', "productID={$product->id}&branch=&type=allstory", $lang->story->viewAll . '<span class="label label-badge label-icon"><i class="icon icon-arrow-right"></i></span>', '', 'class="btn btn-primary btn-circle btn-icon-right btn-sm"');?>
<?php common::printLink('product', 'browse', "productID={$product->id}&branch=&type=allstory", $lang->story->viewAll . '<span class="label label-badge label-icon"><i class="icon icon-arrow-right"></i></span>', '', 'class="btn btn-primary btn-circle btn-icon-right btn-sm" data-app="product"');?>
<?php else:?>
<div class="tile-amount">0</div>
<?php common::printLink('story', 'create', "productID={$product->id}", '<span class="label label-badge label-icon"><i class="icon icon-plus"></i></span>' . $lang->story->create, '', 'class="btn btn-primary btn-circle btn-icon-left btn-sm"');?>
<?php common::printLink('story', 'create', "productID={$product->id}", '<span class="label label-badge label-icon"><i class="icon icon-plus"></i></span>' . $lang->story->create, '', 'class="btn btn-primary btn-circle btn-icon-left btn-sm" data-app="product"');?>
<?php endif;?>
</div>
<ul class="types-line">
@@ -157,7 +157,7 @@ $(function()
</div>
<?php else:?>
<div class="actions">
<?php common::printLink('productplan', 'create', "productID={$product->id}", "<i class='icon icon-plus'></i> " . $lang->productplan->create, '', "class='btn btn-info'");?>
<?php common::printLink('productplan', 'create', "productID={$product->id}", "<i class='icon icon-plus'></i> " . $lang->productplan->create, '', "class='btn btn-info' data-app='product'");?>
</div>
<?php endif;?>
<div class="type-info">
@@ -190,7 +190,7 @@ $(function()
</div>
<?php else:?>
<div class="actions">
<?php common::printLink('release', 'create', "productID={$product->id}", "<i class='icon icon-plus'></i> " . $lang->release->create, '', "class='btn btn-info'");?>
<?php common::printLink('release', 'create', "productID={$product->id}", "<i class='icon icon-plus'></i> " . $lang->release->create, '', "class='btn btn-info' data-app='product'");?>
</div>
<?php endif;?>
<div class="type-info">
+2 -1
View File
@@ -13,7 +13,8 @@
.product-info .progress-info {position: absolute; left: 8px; top: 10px; width: 180px; font-size: 12px;}
.product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 100px;}
.product-info .type-value,
.product-info .type-label {font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.product-info .type-label {font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #838A9D;}
.progress-pie .progress-info>small {color: #838A9D;}
.product-info .type-value {font-size: 14px;}
.product-info .type-value > strong {font-size: 20px; color: #3C4353;}
.product-info .actions {position: absolute; left: 10px; top: 14px;}
+1 -1
View File
@@ -22,7 +22,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
.block-todoes .todoes > li {position: relative; padding: 5px 10px 5px 35px; list-style: none; white-space:nowrap; overflow: auto; overflow-x:hidden;}
.block-todoes .todoes > li:hover {background-color: #e9f2fb;}
.block-todoes .todo-title {padding: 0px;}
.titleBox {max-width: 730px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;}
.titleBox {max-width: 1440px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;}
.block-todoes .todo-pri {margin: 0 5px;}
.block-todoes .todo-time {display: inline-block; padding: 0 5px; font-size: 12px; color: #8e939a; width: 95px; min-width: 95px;}
.block-todoes .todo-check {position: absolute; top: 5px; left: 10px; display: block; width: 20px; height: 20px; font-size: 20px; color: transparent; cursor: pointer; background: #fff; border: 2px solid #eee; border-radius: 50%;}
@@ -5,6 +5,8 @@
.block-issues .c-id {width: 55px;}
.block-issues .c-status {width: 80px;}
.block-issues.block-sm .c-status {text-align: center;}
.c-assignedTo {width: 100px; padding:0px !important;text-align:center;}
.c-severity, .c-pri {text-align:center;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-issues <?php if(!$longBlock) echo 'block-sm';?>'>
@@ -17,7 +19,7 @@
<th class='c-status'><?php echo $lang->issue->severity;?></th>
<th class='c-number'><?php echo $lang->issue->pri;?></th>
<th class='c-user'><?php echo $lang->issue->owner;?></th>
<th class='c-user'><?php echo $lang->issue->assignedTo;?></th>
<th class='c-assignedTo'><?php echo $lang->issue->assignedTo;?></th>
<?php endif;?>
<th class='c-status'><?php echo $lang->issue->status;?></th>
</tr>
@@ -35,7 +37,7 @@
<td class='c-severity'><?php echo zget($lang->issue->severityList, $issue->severity, $issue->severity)?></td>
<td class='c-pri'><?php echo zget($lang->issue->priList, $issue->pri, $issue->pri)?></td>
<td><?php echo zget($users, $issue->owner, $issue->owner)?></td>
<td><?php echo zget($users, $issue->assignedTo, $issue->assignedTo)?></td>
<td class='c-assignedTo'><?php echo zget($users, $issue->assignedTo, $issue->assignedTo)?></td>
<?php endif;?>
<td class='c-status'>
<span class="status-issue status-<?php echo $issue->status?>"><?php echo zget($lang->issue->statusList, $issue->status);?></span>
@@ -3,9 +3,11 @@
<?php else:?>
<style>
.block-risks .c-id {width: 40px;}
.block-risks .c-pri {width: 70px; text-align: center;}
.block-risks .c-strategy, .block-risks .c-status {width: 60px;}
.block-risks .c-user, .block-risks .c-rate, .block-risks .c-category {width: 80px;}
.block-risks .c-pri {width: 85px; text-align: center;}
.block-risks .c-strategy, .block-risks .c-status {width: 80px;}
.block-risks .c-user, .block-risks .c-rate, .block-risks .c-category {width: 110px;}
.c-rate, .c-category {text-align:center;}
.c-assignedTo {width: 100px; padding:0px !important;text-align:center;}
.pri-low {color: #000000;}
.pri-middle {color: #FF9900;}
.pri-high {color: #E53333;}
@@ -23,7 +25,7 @@
<?php if($longBlock):?>
<th class='c-rate'><?php echo $lang->risk->rate;?></th>
<th class='c-pri'><?php echo $lang->risk->pri;?></th>
<th class='c-user'><?php echo $lang->risk->assignedTo;?></th>
<th class='c-assignedTo text-center'><?php echo $lang->risk->assignedTo;?></th>
<th class='c-category'><?php echo $lang->risk->category;?></th>
<?php endif;?>
</tr>
@@ -44,8 +46,8 @@
</td>
<?php if($longBlock):?>
<td class='c-rate'><?php echo $risk->rate?></td>
<td><?php echo "<span class='pri-{$risk->pri}'>" . zget($lang->risk->priList, $risk->pri) . "</span>";?></td>
<td><?php echo zget($users, $risk->assignedTo, $risk->assignedTo)?></td>
<td class='c-pri'><?php echo "<span class='pri-{$risk->pri}'>" . zget($lang->risk->priList, $risk->pri) . "</span>";?></td>
<td class='c-assignedTo'><?php echo zget($users, $risk->assignedTo, $risk->assignedTo)?></td>
<td class='c-category'><?php echo zget($lang->risk->categoryList, $risk->category, $risk->category)?></td>
<?php endif;?>
</tr>
+3
View File
@@ -6,3 +6,6 @@
.c-build, .c-browser, .c-keywords {width: 100px;}
.c-steps {width: 150px;}
.c-pri, .c-severity {width: 80px;}
.c-actions {width: 60px;}
[lang^=de] .c-build, [lang^=fr] .c-build {width: 115px}
@media screen and (max-width: 1366px) {[lang^=de] .c-build, [lang^=fr] .c-build {width: 110px}}
+4
View File
@@ -1,5 +1,9 @@
html[lang='en'] #moduleIdBox .input-group-addon {padding: 5px 23px;}
html[lang='en'] #deadlineTd .input-group-addon {padding: 5px 18px;}
html[lang='zh-cn'] #keywordsAddonLabel, .task {width: 77px;}
html[lang='zh-tw'] #keywordsAddonLabel, .task {width: 77px;}
html[lang='fr'] #keywordsAddonLabel, .task {width: 61px;}
html[lang='de'] #keywordsAddonLabel, .task {width: 73px;}
.ke-toolbar .ke-outline[data-name='savetemplate'] {display: block;}
.ke-outline .ke-icon-savetemplate {background-image: url(theme/default/images/kindeditor/save.gif); background-position: center; width: 56px; height: 20px;}
+1
View File
@@ -6,3 +6,4 @@
#linkBugBox > li {margin-left: -56px;}
#branch {width: 95px;}
#storyIdBox .chosen-auto-max-width {width: 215px !important;}
.form-group {margin-left: 10px; margin-right: 10px;}
+119
View File
@@ -4,8 +4,95 @@ $(function()
var $titleCol = $('#batchCreateForm table thead tr th.c-title');
if($titleCol.width() < 150) $titleCol.width(150);
$('#customField').click(function()
{
hiddenRequireFields();
});
/* Implement a custom form without feeling refresh. */
$('#formSettingForm .btn-primary').click(function()
{
var fields = '';
$('#formSettingForm > .checkboxes > .checkbox-primary > input:checked').each(function()
{
fields += ',' + $(this).val();
});
var link = createLink('custom', 'ajaxSaveCustomFields', 'module=bug&section=custom&key=batchCreateFields');
$.post(link, {'fields' : fields}, function()
{
showCheckedFields(fields);
$('#formSetting').parent().removeClass('open');
if($('#batchCreateForm table thead tr th.c-title').width() < 150) $titleCol.width(150);
var fieldCount = $('#batchCreateForm .table thead>tr>th:visible').length;
$('.form-actions').attr('colspan', fieldCount);
if(fieldCount > 10)
{
$('#batchCreateForm > .table-responsive').removeClass('scroll-none');
$('#batchCreateForm > .table-responsive').css('overflow', 'auto');
}
else
{
$('#batchCreateForm > .table-responsive').addClass('scroll-none');
$('#batchCreateForm > .table-responsive').css('overflow', 'visible');
}
});
return false;
});
})
/**
* Show checked fields.
*
* @param string fields
* @access public
* @return void
*/
function showCheckedFields(fields)
{
showFields = fields;
var fieldList = ',' + fields + ',';
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
{
var field = ',' + $(this).val() + ',';
var $field = $('[name^=' + $(this).val() + ']');
var required = ',' + requiredFields + ',';
var $fieldBox = $('.' + $(this).val() + 'Box' );
if(fieldList.indexOf(field) >= 0 || required.indexOf(field) >= 0)
{
$fieldBox.removeClass('hidden');
$field.removeAttr('disabled');
}
else if(!$fieldBox.hasClass('hidden'))
{
$fieldBox.addClass('hidden');
$field.attr('disabled', true);
}
});
}
/**
* Hidden require field.
*
* @access public
* @return void
*/
function hiddenRequireFields()
{
$('#formSettingForm > .checkboxes > .checkbox-primary > input').each(function()
{
var field = ',' + $(this).val() + ',';
var required = ',' + requiredFields + ',';
if(required.indexOf(field) >= 0) $(this).closest('div').addClass('hidden');
});
}
/**
* Set opened builds.
*
@@ -149,3 +236,35 @@ $(document).keydown(function(event)
inputFocusJump('down');
}
});
/**
* Add item.
*
* @param object $obj
* @access public
* @return void
*/
function addItem(obj)
{
var item = $('#addItem').html().replace(/%i%/g, itemIndex + 1);
$('<tr class="addedItem">' + item + '</tr>').insertAfter($(obj).closest('tr'));
$(obj).closest('tr').next().find(".form-date").datepicker();
$(obj).closest('tr').next().find('div[id$=_chosen]').remove();
$(obj).closest('tr').next().find('.chosen').next('.picker').remove();
$(obj).closest('tr').next().find('.chosen').chosen();
itemIndex ++;
}
/**
* Delete item.
*
* @param object $obj
* @access public
* @return void
*/
function deleteItem(obj)
{
$(obj).closest('tr').remove();
}
+6 -6
View File
@@ -3195,7 +3195,7 @@ class bugModel extends model
echo zget($users, $bug->openedBy);
break;
case 'openedDate':
echo substr($bug->openedDate, 5, 11);
echo helper::isZeroDate($bug->openedDate) ? '' : substr($bug->openedDate, 5, 11);
break;
case 'openedBuild':
$builds = array_flip($builds);
@@ -3216,10 +3216,10 @@ class bugModel extends model
$this->printAssignedHtml($bug, $users);
break;
case 'assignedDate':
echo substr($bug->assignedDate, 5, 11);
echo helper::isZeroDate($bug->assignedDate) ? '' : substr($bug->assignedDate, 5, 11);
break;
case 'deadline':
echo $bug->deadline;
echo helper::isZeroDate($bug->deadline) ? '' : substr($bug->deadline, 5, 11);
break;
case 'resolvedBy':
echo zget($users, $bug->resolvedBy, $bug->resolvedBy);
@@ -3228,7 +3228,7 @@ class bugModel extends model
echo zget($this->lang->bug->resolutionList, $bug->resolution);
break;
case 'resolvedDate':
echo substr($bug->resolvedDate, 5, 11);
echo helper::isZeroDate($bug->resolvedDate) ? '' : substr($bug->resolvedDate, 5, 11);
break;
case 'resolvedBuild':
echo $bug->resolvedBuild;
@@ -3237,13 +3237,13 @@ class bugModel extends model
echo zget($users, $bug->closedBy);
break;
case 'closedDate':
echo substr($bug->closedDate, 5, 11);
echo helper::isZeroDate($bug->closedDate) ? '' : substr($bug->closedDate, 5, 11);
break;
case 'lastEditedBy':
echo zget($users, $bug->lastEditedBy);
break;
case 'lastEditedDate':
echo substr($bug->lastEditedDate, 5, 11);
echo helper::isZeroDate($bug->lastEditedDate) ? '' : substr($bug->lastEditedDate, 5, 11);
break;
case 'actions':
echo $this->buildOperateMenu($bug, 'browse');
+132 -64
View File
@@ -14,6 +14,24 @@
include '../../common/view/header.html.php';
js::set('requiredFields', $config->bug->create->requiredFields);
?>
<?php
$visibleFields = array();
$requiredFields = array();
foreach(explode(',', $showFields) as $field)
{
if($field) $visibleFields[$field] = '';
}
foreach(explode(',', $config->bug->create->requiredFields) as $field)
{
if($field)
{
$requiredFields[$field] = '';
if(strpos(",{$config->bug->list->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = '';
}
}
?>
<?php js::set('showFields', $showFields);?>
<div id='mainContent' class='main-content fade'>
<div class='main-header'>
<h2>
@@ -30,49 +48,32 @@ js::set('requiredFields', $config->bug->create->requiredFields);
<?php endif;?>
</div>
</div>
<?php
$visibleFields = array();
$requiredFields = array();
foreach(explode(',', $showFields) as $field)
{
if($field) $visibleFields[$field] = '';
}
foreach(explode(',', $config->bug->create->requiredFields) as $field)
{
if($field)
{
$requiredFields[$field] = '';
if(strpos(",{$config->bug->list->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = '';
}
}
?>
<form class='main-form' method='post' target='hiddenwin' id='batchCreateForm'>
<div class="table-responsive">
<table class='table table-form'>
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-branch<?php echo zget($visibleFields, $product->type, ' hidden')?>'> <?php echo $lang->product->branch;?></th>
<th class='c-branch<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'> <?php echo $lang->product->branch;?></th>
<th class='c-module<?php echo zget($requiredFields, 'module', '', ' required');?>'> <?php echo $lang->bug->module;?></th>
<?php if($config->systemMode == 'new'):?>
<th class='c-project<?php echo zget($visibleFields, 'project', ' hidden') . zget($requiredFields, 'project', '', ' required');?>'><?php echo (isset($project->model) and $project->model == 'kanban') ? $lang->bug->kanban : $lang->bug->project;?></th>
<th class='c-project<?php echo zget($visibleFields, 'project', ' hidden') . zget($requiredFields, 'project', '', ' required');?> projectBox'><?php echo (isset($project->model) and $project->model == 'kanban') ? $lang->bug->kanban : $lang->bug->project;?></th>
<?php endif;?>
<th class='c-execution<?php echo zget($visibleFields, 'execution', ' hidden') . zget($requiredFields, 'execution', '', ' required');?>'><?php echo (isset($project->model) and $project->model == 'kanban') ? $lang->bug->kanban : $lang->bug->execution;?></th>
<th class='c-execution<?php echo zget($visibleFields, 'execution', ' hidden') . zget($requiredFields, 'execution', '', ' required');?> executionBox'><?php echo (isset($project->model) and $project->model == 'kanban') ? $lang->bug->kanban : $lang->bug->execution;?></th>
<th class='c-build required'><?php echo $lang->bug->openedBuild;?></th>
<th class='c-title required'><?php echo $lang->bug->title;?></th>
<?php if(isset($executionType) and $executionType == 'kanban'):?>
<th class='c-execution'><?php echo $lang->kanbancard->region;?></th>
<th class='c-execution'><?php echo $lang->kanbancard->lane;?></th>
<?php endif;?>
<th class='c-date<?php echo zget($visibleFields, 'deadline', ' hidden') . zget($requiredFields, 'deadline', '', ' required');?>'><?php echo $lang->bug->deadline;?></th>
<th class='c-steps<?php echo zget($visibleFields, 'steps', ' hidden') . zget($requiredFields, 'steps', '', ' required');?>'><?php echo $lang->bug->steps;?></th>
<th class='c-type<?php echo zget($visibleFields, 'type', ' hidden') . zget($requiredFields, 'type', '', ' required');?>'><?php echo $lang->typeAB;?></th>
<th class='c-pri<?php echo zget($visibleFields, 'pri', ' hidden') . zget($requiredFields, 'pri', '', ' required');?>'><?php echo $lang->bug->pri;?></th>
<th class='c-severity<?php echo zget($visibleFields, 'severity', ' hidden') . zget($requiredFields, 'severity', '', ' required');?>'><?php echo $lang->bug->severity;?></th>
<th class='c-os<?php echo zget($visibleFields, 'os', ' hidden') . zget($requiredFields, 'os', '', ' required');?>'><?php echo $lang->bug->os;?></th>
<th class='c-browser<?php echo zget($visibleFields, 'browser', ' hidden') . zget($requiredFields, 'browser', '', ' required');?>'><?php echo $lang->bug->browser;?></th>
<th class='c-keywords<?php echo zget($visibleFields, 'keywords', ' hidden') . zget($requiredFields, 'keywords', '', ' required');?>'><?php echo $lang->bug->keywords;?></th>
<th class='c-date<?php echo zget($visibleFields, 'deadline', ' hidden') . zget($requiredFields, 'deadline', '', ' required');?> deadlineBox'><?php echo $lang->bug->deadline;?></th>
<th class='c-steps<?php echo zget($visibleFields, 'steps', ' hidden') . zget($requiredFields, 'steps', '', ' required');?> stepsBox'><?php echo $lang->bug->steps;?></th>
<th class='c-type<?php echo zget($visibleFields, 'type', ' hidden') . zget($requiredFields, 'type', '', ' required');?> typeBox'><?php echo $lang->typeAB;?></th>
<th class='c-pri<?php echo zget($visibleFields, 'pri', ' hidden') . zget($requiredFields, 'pri', '', ' required');?> priBox'><?php echo $lang->bug->pri;?></th>
<th class='c-severity<?php echo zget($visibleFields, 'severity', ' hidden') . zget($requiredFields, 'severity', '', ' required');?> severityBox'><?php echo $lang->bug->severity;?></th>
<th class='c-os<?php echo zget($visibleFields, 'os', ' hidden') . zget($requiredFields, 'os', '', ' required');?> osBox'><?php echo $lang->bug->os;?></th>
<th class='c-browser<?php echo zget($visibleFields, 'browser', ' hidden') . zget($requiredFields, 'browser', '', ' required');?> browserBox'><?php echo $lang->bug->browser;?></th>
<th class='c-keywords<?php echo zget($visibleFields, 'keywords', ' hidden') . zget($requiredFields, 'keywords', '', ' required');?> keywordsBox'><?php echo $lang->bug->keywords;?></th>
<?php
$extendFields = $this->bug->getFlowExtendFields();
foreach($extendFields as $extendField)
@@ -81,6 +82,7 @@ js::set('requiredFields', $config->bug->create->requiredFields);
echo "<th class='c-extend $required'>{$extendField->name}</th>";
}
?>
<th class='c-actions'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -106,13 +108,13 @@ js::set('requiredFields', $config->bug->create->requiredFields);
$browser = $i == 1 ? '' : 'ditto';
?>
<tr>
<td class='text-center'><?php echo $i;?></td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?>' style='overflow:visible'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td class='text-left'><?php echo $i;?></td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox' style='overflow:visible'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<?php if($config->systemMode == 'new'):?>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?>' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?>' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, 'trunk', "class='form-control chosen' multiple");?></td>
<td>
<div class='input-group'>
@@ -132,18 +134,24 @@ js::set('requiredFields', $config->bug->create->requiredFields);
<td><?php echo html::select("regions[$i]", $regionPairs, $regionID, "class='form-control chosen'");?></td>
<td><?php echo html::select("lanes[$i]", $lanePairs, $laneID, "class='form-control chosen'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?>'><?php echo html::input("deadlines[$i]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?>'><?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?>' style='overflow:visible'> <?php echo html::select("types[$i]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?>' style='overflow:visible'> <?php echo html::select("pris[$i]", $lang->bug->priList, $pri, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?>' style='overflow:visible'><?php echo html::select("severities[$i]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?>' style='overflow:visible'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?>' style='overflow:visible'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?> deadlineBox'><?php echo html::input("deadlines[$i]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?> stepsBox'><?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?> typeBox' style='overflow:visible'> <?php echo html::select("types[$i]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?> priBox' style='overflow:visible'> <?php echo html::select("pris[$i]", $lang->bug->priList, $pri, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?> severityBox' style='overflow:visible'><?php echo html::select("severities[$i]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?> osBox' style='overflow:visible'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?> browserBox' style='overflow:visible'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?> keywordsBox'><?php echo html::input("keywords[$i]", '', "class='form-control'");?></td>
<?php
$this->loadModel('flow');
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
?>
<td class='c-actions text-left'>
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
<?php if($i != 1):?>
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
<?php endif;?>
</td>
</tr>
<?php $i++;?>
<?php endforeach;?>
@@ -161,12 +169,12 @@ js::set('requiredFields', $config->bug->create->requiredFields);
?>
<tr>
<td><?php echo $i;?></td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?>' style='overflow:visible'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox' style='overflow:visible'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<?php if($config->systemMode == 'new'):?>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?>' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?>' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control chosen' multiple");?></td>
<td>
<div class='input-group'>
@@ -186,24 +194,30 @@ js::set('requiredFields', $config->bug->create->requiredFields);
<td><?php echo html::select("regions[$i]", $regionPairs, $regionID, "class='form-control chosen' onchange='setLane(this.value, $i)'");?></td>
<td><?php echo html::select("lanes[$i]", $lanePairs, $laneID, "class='form-control chosen'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?>'><?php echo html::input("deadlines[$i]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?>'><?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?>' style='overflow:visible'> <?php echo html::select("types[$i]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?>' style='overflow:visible'> <?php echo html::select("pris[$i]", $lang->bug->priList, $pri, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?>' style='overflow:visible'><?php echo html::select("severities[$i]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?>' style='overflow:visible'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?>' style='overflow:visible'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?> deadlineBox'><?php echo html::input("deadlines[$i]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?> stepsBox'><?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?> typeBox' style='overflow:visible'> <?php echo html::select("types[$i]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?> priBox' style='overflow:visible'> <?php echo html::select("pris[$i]", $lang->bug->priList, $pri, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?> severityBox' style='overflow:visible'><?php echo html::select("severities[$i]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?> osBox' style='overflow:visible'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?> browserBox' style='overflow:visible'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?> keywordsBox'><?php echo html::input("keywords[$i]", '', "class='form-control'");?></td>
<?php
$this->loadModel('flow');
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
?>
<td class='c-actions text-left'>
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
<?php if($i != 1):?>
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
<?php endif;?>
</td>
</tr>
<?php endfor;?>
</tbody>
<tfoot>
<tr>
<td colspan='<?php echo count($visibleFields) + 3?>' class='text-center form-actions'>
<td colspan='<?php echo count($visibleFields) + 4?>' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php echo html::backButton();?>
</td>
@@ -213,16 +227,17 @@ js::set('requiredFields', $config->bug->create->requiredFields);
</div>
</form>
</div>
<?php js::set('itemIndex', -- $i);?>
<table class='template' id='trTemp'>
<tbody>
<tr>
<td>%s</td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?>' style='overflow:visible'><?php echo html::select("branches[%s]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, \"%s\")'");?></td>
<td><?php echo html::select("modules[%s]", $moduleOptionMenu, $moduleID, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?> productBox' style='overflow:visible'><?php echo html::select("branches[%s]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, \"%s\")'");?></td>
<td><?php echo html::select("modules[%s]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<?php if($config->systemMode == 'new'):?>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?>' style='overflow:visible'><?php echo html::select("projects[%s]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, \"%s\")'");?></td>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[%s]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, \"%s\")'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?>' style='overflow:visible'><?php echo html::select("executions[%s]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, \"%s\")'");?></td>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[%s]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, \"%s\")'");?></td>
<td id='buildBox%s'><?php echo html::select("openedBuilds[%s][]", $builds, '', "class='form-control chosen' multiple");?></td>
<td>
<div class='input-group'>
@@ -238,21 +253,74 @@ js::set('requiredFields', $config->bug->create->requiredFields);
</div>
</div>
</td>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?>'><?php echo html::input("deadlines[%s]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?>'><?php echo html::textarea("stepses[%s]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?>' style='overflow:visible'> <?php echo html::select("types[%s]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?>' style='overflow:visible'> <?php echo html::select("pris[%s]", $lang->bug->priList, '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?>' style='overflow:visible'><?php echo html::select("severities[%s]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?>' style='overflow:visible'> <?php echo html::select("oses[%s]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?>' style='overflow:visible'> <?php echo html::select("browsers[%s]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[%s]", '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?> deadlineBox'><?php echo html::input("deadlines[%s]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?> stepsBox'><?php echo html::textarea("stepses[%s]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?> typeBox' style='overflow:visible'> <?php echo html::select("types[%s]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?> priBox' style='overflow:visible'> <?php echo html::select("pris[%s]", $lang->bug->priList, $pri, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?> severityBox' style='overflow:visible'><?php echo html::select("severities[%s]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?> osBox' style='overflow:visible'> <?php echo html::select("oses[%s]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?> browserBox' style='overflow:visible'> <?php echo html::select("browsers[%s]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?> keywordsBox'><?php echo html::input("keywords[%s]", '', "class='form-control'");?></td>
<?php
$this->loadModel('flow');
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[%s]") . "</td>";
?>
<td class='c-actions text-left'>
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
</td>
</tr>
</tbody>
</table>
<div>
<?php $i = '%i%';?>
<table class='hidden'>
<tr id='addItem' class='hidden'>
<td><?php echo $i;?></td>
<td class='<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox' style='overflow:visible'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control chosen' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<?php if($config->systemMode == 'new'):?>
<td class='<?php echo zget($visibleFields, 'project', ' hidden')?> projectBox' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange = 'loadProductExecutionsByProject($productID, this.value, $i)'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'execution', ' hidden')?> executionBox' style='overflow:visible'><?php echo html::select("executions[$i]", $executions, $executionID, "class='form-control chosen' onchange='loadExecutionBuilds($productID, this.value, $i)'");?></td>
<td id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control chosen' multiple");?></td>
<td>
<div class='input-group'>
<div class="input-control has-icon-right">
<?php echo html::input("title[$i]", '', "class='form-control title-import'");?>
<div class="colorpicker">
<button type="button" class="btn btn-link dropdown-toggle" data-toggle="dropdown"><span class="cp-title"></span><span class="color-bar"></span><i class="ic"></i></button>
<ul class="dropdown-menu clearfix">
<li class="heading"><?php echo $lang->bug->colorTag;?><i class="icon icon-close"></i></li>
</ul>
<?php echo html::hidden("color[$i]", '', "data-provide='colorpicker' data-icon='color' data-wrapper='input-control-icon-right' data-update-color='#title\\[$i\\]'");?>
</div>
</div>
</div>
</td>
<?php if(isset($executionType) and $executionType == 'kanban'):?>
<td><?php echo html::select("regions[$i]", $regionPairs, $regionID, "class='form-control chosen' onchange='setLane(this.value, $i)'");?></td>
<td><?php echo html::select("lanes[$i]", $lanePairs, $laneID, "class='form-control chosen'");?></td>
<?php endif;?>
<td class='<?php echo zget($visibleFields, 'deadline', 'hidden')?> deadlineBox'><?php echo html::input("deadlines[$i]", '', "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?> stepsBox'><?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?> typeBox' style='overflow:visible'> <?php echo html::select("types[$i]", $lang->bug->typeList, $type, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'pri', 'hidden')?> priBox' style='overflow:visible'> <?php echo html::select("pris[$i]", $lang->bug->priList, $pri, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?> severityBox' style='overflow:visible'><?php echo html::select("severities[$i]", $lang->bug->severityList, '3', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?> osBox' style='overflow:visible'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?> browserBox' style='overflow:visible'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?> keywordsBox'><?php echo html::input("keywords[$i]", '', "class='form-control'");?></td>
<?php
$this->loadModel('flow');
foreach($extendFields as $extendField) echo "<td" . (($extendField->control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->flow->getFieldControl($extendField, '', $extendField->field . "[$i]") . "</td>";
?>
<td class='c-actions text-left'>
<a href='javascript:;' onclick='addItem(this)' class='btn btn-link'><i class='icon-plus'></i></a>
<a href='javascript:;' onclick='deleteItem(this)' class='btn btn-link'><i class='icon icon-close'></i></a>
</td>
</tr>
</table>
</div>
<?php js::set('branch', $branch)?>
<?php if(isonlybody()):?>
<style>
+1 -1
View File
@@ -131,7 +131,7 @@
}
?>
<td class='<?php echo zget($visibleFields, 'assignedTo', ' hidden')?>' style='overflow:visible'><?php echo html::select("assignedTos[$bugID]", $assignedToList, $bug->assignedTo, "class='form-control picker-select' data-drop-width='135px'");?></td>
<td class='<?php echo zget($visibleFields, 'deadline', ' hidden')?>' style='overflow:visible'><?php echo html::input("deadlines[$bugID]", $bug->deadline, "class='form-control form-date'");?></td>
<td class='<?php echo zget($visibleFields, 'deadline', ' hidden')?>' style='overflow:visible'><?php echo html::input("deadlines[$bugID]", helper::isZeroDate($bug->deadline) ? '' : substr($bug->deadline, 5, 11), "class='form-control form-date'");?></td>
<td <?php echo zget($visibleFields, 'os', "class='hidden'")?>><?php echo html::select("os[$bugID]", $osList, $bug->os, 'class=form-control');?></td>
<td <?php echo zget($visibleFields, 'browser', "class='hidden'")?>><?php echo html::select("browsers[$bugID]", $browserList, $bug->browser, 'class=form-control');?></td>
<td <?php echo zget($visibleFields, 'keywords', "class='hidden'")?>><?php echo html::input("keywords[$bugID]", $bug->keywords, 'class=form-control');?></td>
+1 -1
View File
@@ -312,7 +312,7 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
<td>
<div class='input-group'>
<?php if($showStory):?>
<span class='input-group-addon'><?php echo $lang->bug->task?></span>
<span class='input-group-addon task'><?php echo $lang->bug->task?></span>
<?php endif;?>
<?php echo html::select('task', '', $taskID, "class='form-control chosen'") . html::hidden('oldTaskID', $taskID);?>
</div>
+1 -1
View File
@@ -160,7 +160,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</tr>
<tr>
<th><?php echo $lang->bug->deadline;?></th>
<td><?php echo html::input('deadline', $bug->deadline, "class='form-control form-date'");?></td>
<td><?php echo html::input('deadline', helper::isZeroDate($bug->deadline) ? '' : $bug->deadline, "class='form-control form-date'");?></td>
</tr>
<tr>
<th><?php echo $lang->bug->feedbackBy;?></th>
+1 -1
View File
@@ -224,7 +224,7 @@
<th><?php echo $lang->bug->deadline;?></th>
<td>
<?php
if($bug->deadline) echo $bug->deadline;
if($bug->deadline) echo helper::isZeroDate($bug->deadline) ? '' : substr($bug->deadline, 5, 11);
if(isset($bug->delay)) printf($lang->bug->delayWarning, $bug->delay);
?>
</td>
+1
View File
@@ -1 +1,2 @@
.table table td,.outer .table table tbody > tr:last-child td {padding: 2px 0 2px 5px !important; border: none !important;}
.c-pri{width: 70px;}
+16 -8
View File
@@ -20,6 +20,7 @@ $(function()
});
</script>
<?php else:?>
<?php js::set('requiredFields', $requiredFields);?>
<div id="mainContent" class="main-content">
<div class="main-header clearfix">
<h2><?php echo $lang->caselib->import;?></h2>
@@ -29,13 +30,13 @@ $(function()
<thead>
<tr>
<th class='c-number'><?php echo $lang->testcase->id?></th>
<th><?php echo $lang->testcase->title?></th>
<th class='c-module'><?php echo $lang->testcase->module?></th>
<th class='c-status'><?php echo $lang->testcase->pri?></th>
<th class='c-status'><?php echo $lang->testcase->type?></th>
<th><?php echo $lang->testcase->stage?></th>
<th class='c-text'><?php echo $lang->testcase->keywords?></th>
<th><?php echo $lang->testcase->precondition?></th>
<th class='c-title' id='title'> <?php echo $lang->testcase->title?></th>
<th class='c-module' id='module'> <?php echo $lang->testcase->module?></th>
<th class='c-pri' id='pri'> <?php echo $lang->testcase->pri?></th>
<th class='c-type' id='type'> <?php echo $lang->testcase->type?></th>
<th class='c-stage' id='stage'> <?php echo $lang->testcase->stage?></th>
<th class='c-text' id='keywords'> <?php echo $lang->testcase->keywords?></th>
<th class='c-precondition' id='precondition'><?php echo $lang->testcase->precondition?></th>
<th class='c-case-step col-content'>
<table class='w-p100 table-borderless'>
<tr>
@@ -127,6 +128,13 @@ $(function()
<style>#mainContent .col-content{display: none;}</style>
<?php endif;?>
<script>
$(function(){$.fixedTableHead('#showData');});
$(function()
{
$.fixedTableHead('#showData');
$("#showData th").each(function()
{
if(requiredFields.indexOf(this.id) !== -1) $("#" + this.id).addClass('required');
});
});
</script>
<?php include '../../common/view/footer.html.php';?>
+12 -11
View File
@@ -323,17 +323,18 @@ if($config->systemMode == 'new') $lang->execution->menu->more = array('link' =>
/* Execution menu order. */
$lang->execution->menuOrder[5] = 'task';
$lang->execution->menuOrder[10] = 'kanban';
$lang->execution->menuOrder[15] = 'burn';
$lang->execution->menuOrder[20] = 'view';
$lang->execution->menuOrder[25] = 'story';
$lang->execution->menuOrder[30] = 'qa';
$lang->execution->menuOrder[35] = 'repo';
$lang->execution->menuOrder[40] = 'devops';
$lang->execution->menuOrder[45] = 'doc';
$lang->execution->menuOrder[50] = 'build';
$lang->execution->menuOrder[55] = 'release';
$lang->execution->menuOrder[60] = 'action';
$lang->execution->menuOrder[65] = 'settings';
$lang->execution->menuOrder[15] = 'CFD';
$lang->execution->menuOrder[20] = 'burn';
$lang->execution->menuOrder[25] = 'view';
$lang->execution->menuOrder[30] = 'story';
$lang->execution->menuOrder[35] = 'qa';
$lang->execution->menuOrder[40] = 'repo';
$lang->execution->menuOrder[45] = 'devops';
$lang->execution->menuOrder[50] = 'doc';
$lang->execution->menuOrder[55] = 'build';
$lang->execution->menuOrder[60] = 'release';
$lang->execution->menuOrder[65] = 'action';
$lang->execution->menuOrder[70] = 'settings';
$lang->execution->menu->doc['subMenu'] = new stdclass();
+1 -1
View File
@@ -281,7 +281,7 @@ $lang->testcase->caselib = '用例库';
$lang->devops->compile = '构建';
$lang->devops->mr = '合并请求';
$lang->devops->repo = '版本库';
$lang->devops->repo = '代码库';
$lang->devops->rules = '指令';
$lang->devops->settings = '合并请求设置';
$lang->devops->set = '设置';
+1
View File
@@ -2496,6 +2496,7 @@ EOD;
if($module == 'company' and $method == 'dynamic') return true;
if($module == 'action' and $method == 'editcomment') return true;
if($module == 'action' and $method == 'comment') return true;
if($module == 'report' and $method == 'export') return true;
if(!isset($acls['views'][$menu])) return false;
return true;
+13 -1
View File
@@ -16,10 +16,12 @@
#formSettingForm .checkboxes {padding: 10px 3px;}
#formSettingForm .checkbox-primary {width: 50%; float: left; margin: 3px 0;}
#formSetting .btn {margin-right: 8px;}
[lang^='de'] #formSetting {min-width: 360px;}
[lang^='fr'] #formSetting {min-width: 320px;}
</style>
<button type="button" title="<?php echo $lang->customField;?>" class="btn btn-link" id="customField" data-toggle="dropdown"><i class="icon icon-cog"></i></button>
<div class="dropdown-menu pull-right" id="formSetting">
<form class='with-padding load-indicator' id='formSettingForm' method='post' target='hiddenwin' action='<?php echo $customLink?>'>
<form class='with-padding load-indicator not-watch' id='formSettingForm' method='post' target='hiddenwin' action='<?php echo $customLink?>'>
<div><?php echo $lang->customField;?></div>
<div class="clearfix checkboxes">
<?php echo html::checkbox('fields', $customFields, $showFields);?>
@@ -35,6 +37,16 @@
var $formSetting = $('#formSetting');
$formSetting.on('click', '.close-dropdown', function()
{
if(showFields != undefined)
{
var fieldList = ',' + showFields + ',';
$('#formSettingForm > .checkboxes > .checkbox-primary > input:visible').each(function()
{
var field = ',' + $(this).val() + ',';
$(this).prop('checked', fieldList.indexOf(field) >= 0);
});
}
$formSetting.parent().removeClass('open');
}).on('click', function(e){e.stopPropagation()});
</script>
+8
View File
@@ -25,7 +25,15 @@ $(function()
{
if(!rowTpl) rowTpl = $('#trTemp tbody').html();
if(!$formTbody) $formTbody = $form.find('table > tbody');
var lastIndex = parseInt($formTbody.find('tr:last > td:first').text());
var moduleArr = ['task', 'story', 'bug', 'testcase'];
if($.inArray(config.currentModule, moduleArr) >= 0 && config.currentMethod == 'batchcreate')
{
lastIndex = itemIndex;
itemIndex ++;
}
var $newRow = $(rowTpl.replace(/%s/g, lastIndex + 1));
$newRow.find('.chosen').chosen();
$newRow.find('.iframe').modalTrigger({iframe:true});
+4 -1
View File
@@ -676,14 +676,17 @@ class custom extends control
$account = $this->app->user->account;
if($this->server->request_method == 'POST')
{
$fields = $this->post->fields;
$fields = $this->post->fields;
if(is_array($fields)) $fields = join(',', $fields);
$this->loadModel('setting')->setItem("$account.$module.$section.$key", $fields);
if(in_array($module, array('task', 'testcase', 'story')) and $section == 'custom' and in_array($key, array('createFields', 'batchCreateFields'))) return;
if($module == 'bug' and $section == 'custom' and $key == 'batchCreateFields') return;
}
else
{
$this->loadModel('setting')->deleteItems("owner=$account&module=$module&section=$section&key=$key");
}
return print(js::reload('parent'));
}
+3 -2
View File
@@ -12,10 +12,11 @@
<?php endif;?>
</div>
<div class="info">
<div class="version">
<?php $version = $version ? $version : $doc->version;?>
<div class="version" data-version='<?php echo $version;?>'>
<div class='btn-group'>
<a href='javascript:;' class='btn btn-link btn-limit text-ellipsis' data-toggle='dropdown' style="max-width: 120px;">
#<?php echo $version ? $version : $doc->version;?>
#<?php echo $version;?>
<span class="caret"></span>
</a>
<ul class='dropdown-menu doc-version-menu' style='max-height:240px; max-width: 300px; overflow-y:auto'>
+82 -2
View File
@@ -412,13 +412,26 @@ class execution extends control
}
elseif($groupBy == 'assignedTo' and $filter == 'undone')
{
$multiTaskCount = array();
foreach($groupTasks as $assignedTo => $tasks)
{
foreach($tasks as $i => $task)
{
if($task->status != 'wait' and $task->status != 'doing')
{
$allCount -= 1;
if($task->mode == 'multi')
{
if(!isset($multiTaskCount[$task->id]))
{
$multiTaskCount[$task->id] = true;
$allCount -= 1;
}
}
else
{
$allCount -= 1;
}
unset($groupTasks[$assignedTo][$i]);
}
}
@@ -805,6 +818,14 @@ class execution extends control
}
$actionURL = $this->createLink('execution', 'story', "executionID=$executionID&orderBy=$orderBy&type=bySearch&queryID=myQueryID");
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$branchOption = array();
foreach($branchGroups as $productID => $branches)
{
foreach($branches as $branchID => $name)
{
$branchOption[$branchID] = $name;
}
}
$this->execution->buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, 'executionStory', $executionID);
/* Header and position. */
@@ -867,9 +888,10 @@ class execution extends control
$this->view->pager = $pager;
$this->view->setModule = true;
$this->view->branchGroups = $branchGroups;
$this->view->branchOption = $branchOption;
$this->view->canBeChanged = common::canModify('execution', $execution); // Determines whether an object is editable.
$this->view->showBranch = $showBranch;
$this->view->storyStages = $this->product->batchGetStoryStage($stories);
$this->view->storyStages = $this->product->batchGetStoryStage($stories);
$this->display();
}
@@ -1283,6 +1305,64 @@ class execution extends control
$this->display();
}
/**
* Kanban CFD.
*
* @param int $executionID
* @param string $type
* @access public
* @return void
*/
public function cfd($executionID = 0, $type = 'story')
{
$execution = $this->commonAction($executionID);
$executionID = $execution->id;
$this->loadModel('kanban');
$this->app->loadClass('date');
$end = helper::today() > $execution->end ? $execution->end : helper::today();
if(helper::today() > $execution->end)
{
if(date($execution->end, strtotime('-14 days')) > $execution->begin)
{
$begin = date($execution->end, strtotime('-14 days'));
}
else
{
$begin = $execution->begin;
}
}
elseif(($execution->begin < helper::today()) and (helper::today() < $execution->end))
{
$begin = (date('Y-m-d', strtotime('-14 days')) < $execution->begin) ? $execution->begin : date('Y-m-d', strtotime('-14 days'));
}
$dateList = date::getDateList($begin, $end, 'Y-m-d', '');
$this->view->title = $this->lang->execution->CFD;
$this->view->type = $type;
$this->view->execution = $execution;
$this->view->executionName = $execution->name;
$this->view->executionID = $executionID;
$this->view->chartData = $this->execution->buildCFDData($executionID, $dateList, $type);
$this->display();
}
/**
* Compute cfd datas.
*
* @param string $reload
* @param int $executionID
* @access public
* @return void
*/
public function computeCFD($reload = 'no', $executionID = 0)
{
$this->execution->computeCFD($executionID);
if($reload == 'yes') return print(js::reload('parent'));
}
/**
* Fix burn for first date.
*
+11
View File
@@ -0,0 +1,11 @@
.main-content > h2 {font-size: 16px;}
#cfdWrapper {max-width: 1400px; margin: 0 auto; padding: 25px 100px 10px; position: relative;}
#cfdYUnit {position: absolute; color: #CBD0DB; top: 0; left: 90px;}
#cfdXUnit {position: absolute; color: #CBD0DB; bottom: 20px; right: 60px;}
#cfdLegend {position: absolute; right: 0; width: 80px; height: 60px; top: 50%; margin-top: -30px; line-height: 30px; color: #838A9D; font-size: 12px;}
#cfdLegend > div {position: relative; padding-left: 30px;}
#cfdLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px; background: #EEEEEE;}
#cfdLegend .line-real .bg-primary {background: #1183fb;}
#cfdLegend .line-real .bg-delay {background: red;}
.pull-left .input-control {margin-right: 10px;}
+1
View File
@@ -10,3 +10,4 @@ th.c-deadline {text-align: center;}
.btn-toolbar > .btn {margin-right: 5px !important;}
#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;}
View File
+57 -2
View File
@@ -235,10 +235,12 @@ function createLaneMenu(options)
var privs = lane.actions;
if(!privs.length) return [];
var items = [];
var items = [];
var regionID = lane.$kanbanData.region;
var kanbanID = lane.$kanbanData.kanban;
if(privs.includes('editLaneName')) items.push({label: kanbanLang.editLaneName, icon: 'edit', url: createLink('kanban', 'editLaneName', 'laneID=' + lane.id + '&executionID=0&from=kanban'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '635px'}});
if(privs.includes('editLaneColor')) items.push({label: kanbanLang.editLaneColor, icon: 'color', url: createLink('kanban', 'editLaneColor', 'laneID=' + lane.id + '&executionID=0&from=kanban'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '635px'}});
if(privs.includes('deleteLane')) items.push({label: kanbanLang.deleteLane, icon: 'trash', url: createLink('kanban', 'deleteLane', 'lane=' + lane.id), attrs: {'target': 'hiddenwin'}});
if(privs.includes('deleteLane')) items.push({label: kanbanLang.deleteLane, icon: 'trash', url: createLink('kanban', 'deleteLane', 'regionID=' + regionID + '&kanbanID=' + kanbanID + '&lane=' + lane.id), attrs: {'target': 'hiddenwin'}});
var bounds = options.$trigger[0].getBoundingClientRect();
items.$options = {x: bounds.right, y: bounds.top};
@@ -297,6 +299,59 @@ function createColumnCreateMenu(options)
return items;
}
/**
* Update region name.
*
* @param int $regionID
* @param string $name
* @access public
* @return void
*/
function updateRegionName(regionID, name)
{
$('.region[data-id="' + regionID + '"] > .region-header > strong:first').text(name);
}
/**
* Update lane name.
*
* @param int $laneID
* @param string $name
* @access public
* @return void
*/
function updateLaneName(laneID, name)
{
$('.kanban-lane[data-id="' + laneID + '"] > .kanban-lane-name > span').text(name);
}
/**
* Update lane color.
*
* @param int $laneID
* @param string $color
* @access public
* @return void
*/
function updateLaneColor(laneID, color)
{
$('.kanban-lane[data-id="' + laneID + '"] > .kanban-lane-name').css('background-color', color);
}
/**
* Update column name.
*
* @param int $columnID
* @param string $name
* @param string $color
* @access public
* @return void
*/
function updateColumnName(columnID, name, color)
{
$('.kanban-col[data-id="' + columnID + '"] > div.title > span:first').text(name).css('color', color);
}
/**
* Hide kanban action
*/
+14
View File
@@ -1,3 +1,17 @@
/**
* Update column name.
*
* @param int $columnID
* @param string $name
* @param string $color
* @access public
* @return void
*/
function updateColumnName(columnID, name, color)
{
$('.kanban-col[data-id="' + columnID + '"] > div.title > span:first').text(name).css('color', color);
}
/**
* Change view.
*
+7
View File
@@ -118,6 +118,7 @@ $lang->execution->relatedMember = 'Teammitglieder';
$lang->execution->watermark = 'Exported by ZenTao';
$lang->execution->burnXUnit = '(Date)';
$lang->execution->burnYUnit = '(Hours)';
$lang->execution->count = '(Count)';
$lang->execution->waitTasks = 'Waiting Tasks';
$lang->execution->viewByUser = 'By User';
$lang->execution->oneProduct = "Only one stage can be linked {$lang->productCommon}";
@@ -165,6 +166,10 @@ $lang->execution->lifeTimeList['short'] = "Short-Term";
$lang->execution->lifeTimeList['long'] = "Long-Term";
$lang->execution->lifeTimeList['ops'] = "DevOps";
$lang->execution->cfdTypeList['story'] = "{$lang->SRCommon}";
$lang->execution->cfdTypeList['task'] = "Task";
$lang->execution->cfdTypeList['bug'] = "Bug";
$lang->team = new stdclass();
$lang->team->account = 'Konto';
$lang->team->role = 'Rolle';
@@ -221,6 +226,8 @@ $lang->execution->build = 'Builds';
$lang->execution->testtask = 'Testaufgaben';
$lang->execution->burn = 'Burndown';
$lang->execution->computeBurn = 'Aktualisieren';
$lang->execution->CFD = 'Cumulative Flow diagrams';
$lang->execution->computeCFD = 'Compute Cumulative Flow diagrams';
$lang->execution->burnData = 'Burndown Daten';
$lang->execution->fixFirst = 'Bearbeite Mannstunden des ersten Tags';
$lang->execution->team = 'Teammitglieder';
+7
View File
@@ -118,6 +118,7 @@ $lang->execution->relatedMember = 'Team';
$lang->execution->watermark = 'Exported by ZenTao';
$lang->execution->burnXUnit = '(Date)';
$lang->execution->burnYUnit = '(Hours)';
$lang->execution->count = '(Count)';
$lang->execution->waitTasks = 'Waiting Tasks';
$lang->execution->viewByUser = 'By User';
$lang->execution->oneProduct = "Only one stage can be linked {$lang->productCommon}";
@@ -165,6 +166,10 @@ $lang->execution->lifeTimeList['short'] = "Short-Term";
$lang->execution->lifeTimeList['long'] = "Long-Term";
$lang->execution->lifeTimeList['ops'] = "DevOps";
$lang->execution->cfdTypeList['story'] = "{$lang->SRCommon}";
$lang->execution->cfdTypeList['task'] = "Task";
$lang->execution->cfdTypeList['bug'] = "Bug";
$lang->team = new stdclass();
$lang->team->account = 'User';
$lang->team->role = 'Role';
@@ -221,6 +226,8 @@ $lang->execution->build = 'Build List';
$lang->execution->testtask = 'Request';
$lang->execution->burn = 'Burndown';
$lang->execution->computeBurn = 'Update';
$lang->execution->CFD = 'Cumulative Flow diagrams';
$lang->execution->computeCFD = 'Compute Cumulative Flow diagrams';
$lang->execution->burnData = 'Burndown Data';
$lang->execution->fixFirst = 'Edit 1st-Day Estimates';
$lang->execution->team = 'Members';
+7
View File
@@ -118,6 +118,7 @@ $lang->execution->relatedMember = 'Equipe';
$lang->execution->watermark = 'Exporté par ZenTao';
$lang->execution->burnXUnit = '(Date)';
$lang->execution->burnYUnit = '(Hours)';
$lang->execution->count = '(Count)';
$lang->execution->waitTasks = 'Waiting Tasks';
$lang->execution->viewByUser = 'Par Utilisateur';
$lang->execution->oneProduct = "Only one stage can be linked {$lang->productCommon}";
@@ -165,6 +166,10 @@ $lang->execution->lifeTimeList['short'] = "Short-Term";
$lang->execution->lifeTimeList['long'] = "Long-Term";
$lang->execution->lifeTimeList['ops'] = "DevOps";
$lang->execution->cfdTypeList['story'] = "{$lang->SRCommon}";
$lang->execution->cfdTypeList['task'] = "Task";
$lang->execution->cfdTypeList['bug'] = "Bug";
$lang->team = new stdclass();
$lang->team->account = 'Utilisateur';
$lang->team->role = 'Rôle';
@@ -221,6 +226,8 @@ $lang->execution->build = 'Liste Builds';
$lang->execution->testtask = 'Recette';
$lang->execution->burn = ' Atterrissage';
$lang->execution->computeBurn = 'Calculer';
$lang->execution->CFD = 'Cumulative Flow diagrams';
$lang->execution->computeCFD = 'Compute Cumulative Flow diagrams';
$lang->execution->burnData = "Données d'atterrissage";
$lang->execution->fixFirst = 'Fixer 1er-Jour Estimation';
$lang->execution->team = 'Membres';
+7
View File
@@ -118,6 +118,7 @@ $lang->execution->relatedMember = '相关成员';
$lang->execution->watermark = '由禅道导出';
$lang->execution->burnXUnit = '(日期)';
$lang->execution->burnYUnit = '(工时)';
$lang->execution->count = '(数量)';
$lang->execution->waitTasks = '待处理';
$lang->execution->viewByUser = '按用户查看';
$lang->execution->oneProduct = "阶段只能关联一个{$lang->productCommon}";
@@ -165,6 +166,10 @@ $lang->execution->lifeTimeList['short'] = "短期";
$lang->execution->lifeTimeList['long'] = "长期";
$lang->execution->lifeTimeList['ops'] = "运维";
$lang->execution->cfdTypeList['story'] = "{$lang->SRCommon}";
$lang->execution->cfdTypeList['task'] = "任务";
$lang->execution->cfdTypeList['bug'] = "Bug";
$lang->team = new stdclass();
$lang->team->account = '用户';
$lang->team->role = '角色';
@@ -221,6 +226,8 @@ $lang->execution->build = '所有版本';
$lang->execution->testtask = '测试单';
$lang->execution->burn = '燃尽图';
$lang->execution->computeBurn = '更新燃尽图';
$lang->execution->CFD = '累积流图';
$lang->execution->computeCFD = '更新累积流图';
$lang->execution->burnData = '燃尽图数据';
$lang->execution->fixFirst = '修改首天工时';
$lang->execution->team = '团队成员';
+130
View File
@@ -68,6 +68,7 @@ class executionModel extends model
{
$this->lang->execution->menu = new stdclass();
$this->lang->execution->menu->kanban = array('link' => "{$this->lang->kanban->common}|execution|kanban|executionID=%s");
$this->lang->execution->menu->CFD = array('link' => "{$this->lang->execution->CFD}|execution|cfd|executionID=%s");
$this->lang->execution->menu->build = array('link' => "{$this->lang->build->common}|execution|build|executionID=%s");
$this->lang->execution->dividerMenu = '';
$this->lang->execution->accessDenied = str_replace($this->lang->executionCommon, $this->lang->execution->kanban, $this->lang->execution->accessDenied);
@@ -2997,6 +2998,75 @@ class executionModel extends model
return $burns;
}
/**
* Compute cfd of a execution.
*
* @param int $executionID
* @access public
* @return array
*/
public function computeCFD($executionID = 0)
{
$today = helper::today();
$executions = $this->dao->select('id, code')->from(TABLE_EXECUTION)
->where('type')->eq('kanban')
->andWhere('status')->notin('done,closed,suspended')
->beginIF($executionID)->andWhere('id')->in($executionID)->fi()
->fetchPairs();
if(!$executions) return array();
/* Update today's data of cfd. */
$cells = $this->dao->select("t1.id, t1.kanban as execution, t1.`column`, t1.type, t1.cards, t1.lane, t2.name, t2.parent")
->from(TABLE_KANBANCELL)->alias('t1')
->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.column = t2.id')
->where('t1.kanban')->in(array_keys($executions))
->andWhere('t2.deleted')->eq('0')
->andWhere('t1.type')->in('story,bug,task')
->orderBy('t2.id asc')
->fetchAll('id');
/* Group by type/name/execution/colID. */
$columnGroup = array();
$parentNames = array();
foreach($cells as $id => $column)
{
if($column->parent == '-1')
{
$parentNames[$column->column] = $column->name;
continue;
}
$column->name = isset($parentNames[$column->parent]) ? $parentNames[$column->parent] . "($column->name)" : $column->name;
$columnGroup[$column->execution][$column->type][$column->name][$column->lane][$column->column] = $column;
}
foreach($columnGroup as $executionID => $executionGroup)
{
foreach($executionGroup as $type => $columns)
{
foreach($columns as $colName => $laneGroup)
{
$cfd = new stdclass();
$cfd->count = 0;
$cfd->date = $today;
$cfd->type = $type;
foreach($laneGroup as $laneID => $columnGroup)
{
foreach($columnGroup as $colID => $columnCard)
{
$cards = trim($columnCard->cards, ',');
$cfd->count += $cards ? count(explode(',', $cards)) : 0;
}
}
$cfd->name = $colName;
$cfd->execution = $executionID;
$this->dao->replace(TABLE_CFD)->data($cfd)->exec();
}
}
}
}
/**
* Fix burn for first day.
*
@@ -3134,6 +3204,66 @@ class executionModel extends model
if($todayTag > $counts) return array_slice($sets, $todayTag - $counts, $counts);
}
/**
* Build CFD data.
*
* @param int $executionID
* @param string $type
* @param array $dateList
* @access public
* @return array
*/
public function buildCFDData($executionID, $dateList, $type)
{
$this->loadModel('report');
$setGroup = $this->getCFDData($executionID, $dateList, $type);
if(empty($setGroup)) return array();
$chartData['labels'] = $this->report->convertFormat($dateList, DT_DATE5);
$chartData['line'] = array();
foreach($setGroup as $name => $sets)
{
$chartData['line'][$name] = $this->report->createSingleJSON($sets, $dateList);
}
return $chartData;
}
/**
* Get CFD data to display.
*
* @param int $executionID
* @param string $type
* @param array $dateList
* @access public
* @return array
*/
public function getCFDData($executionID = 0, $dateList = array(), $type = 'story')
{
$execution = $this->getById($executionID);
$setGroup = $this->dao->select("date, `count` AS value, `name`")->from(TABLE_CFD)
->where('execution')->eq((int)$executionID)
->andWhere('type')->eq($type)
->andWhere('date')->in($dateList)
->orderBy('date DESC, id asc')->fetchGroup('name', 'date');
$data = array();
foreach($setGroup as $name => $sets)
{
foreach($sets as $date => $set)
{
if($date < $execution->begin) continue;
$data[$name][$date] = $set;
}
}
return $data;
}
/**
* Get taskes by search.
*
+113
View File
@@ -0,0 +1,113 @@
<?php
/**
* The burn view file of execution 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) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package execution
* @version $Id: cfd.html.php 4164 2013-01-20 08:27:55Z wwccss $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('executionID', $executionID);?>
<?php js::set('executionName', $execution->name);?>
<?php js::set('watermark', $lang->execution->watermark);?>
<?php js::set('cfdXUnit', $lang->execution->burnXUnit);?>
<?php js::set('cfdYUnit', $lang->execution->burnYUnit);?>
<?php js::import($jsRoot . 'echarts/echarts.common.min.js'); ?>
<?php js::import($jsRoot . 'html2canvas/min.js'); ?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<?php
if(strpos('wait,doing', $execution->status) !== false)
{
common::printLink('execution', 'computeCFD', "reload=yes&executionID=$executionID", '<i class="icon icon-refresh"></i> ' . $lang->execution->computeCFD, 'hiddenwin', "title='{$lang->execution->computeCFD}' class='btn btn-primary' id='computeCFD'");
echo '<div class="space"></div>';
}
?>
<div class='input-control w-100px'>
<?php echo html::select('type', $lang->execution->cfdTypeList, $type, "class='form-control chosen'");?>
</div>
</div>
</div>
<div id='mainContent' class='main-content'>
<h2 class='text-center'><?php echo $executionName . ' - ' . zget($lang->execution->cfdTypeList, $type) . $lang->execution->CFD;?></h2>
<div id="cfdWrapper">
<div id="cfdChart">
<canvas id="cfdCanvas" width='1400' height='600'></canvas>
</div>
<div id="cfdYUnit"><?php echo $lang->execution->count;?></div>
<div id="cfdXUnit"><?php echo $lang->execution->burnXUnit;?></div>
</div>
</div>
<script>
var series = [];
var colors = ['#33B4DB', '#7ECF69', '#FFC73A', '#FF5A61', '#50C8D0', '#AF5AFF', '#4EA3FF', '#6C73FF', '#FF8C5A'];
var i = 0;
<?php foreach($chartData['line'] as $label => $set):?>
series.push({
name: '<?php echo $label;?>',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: <?php echo $set;?>
})
i ++;
<?php endforeach;?>
var chartDom = document.getElementById('cfdCanvas');
var myChart = echarts.init(chartDom);
var option;
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: <?php echo json_encode($chartData['labels'])?>,
}
],
yAxis: [
{
type: 'value'
}
],
series: series,
};
option && myChart.setOption(option);
$('#type').change(function()
{
location.href = createLink('execution', 'cfd', 'executionID=' + executionID + '&type=' + $(this).val());
});
</script>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -231,7 +231,7 @@
<tr id="story<?php echo $story->id;?>" data-id='<?php echo $story->id;?>' data-order='<?php echo $story->order ?>' data-estimate='<?php echo $story->estimate?>' data-cases='<?php echo zget($storyCases, $story->id, 0)?>'>
<?php foreach($setting as $key => $value)
{
$this->story->printCell($value, $story, $users, '', $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', '', $execution, $showBranch);
$this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', '', $execution, $showBranch);
}
?>
</tr>
+1 -1
View File
@@ -52,7 +52,7 @@
<td><?php echo zget($lang->testcase->typeList, $case->type);?></td>
<td><?php echo zget($users, $case->openedBy);?></td>
<td><?php echo zget($users, $case->lastRunner);?></td>
<td><?php if(!helper::isZeroDate($case->lastRunDate)) echo date(DT_MONTHTIME1, strtotime($case->lastRunDate));?></td>
<td><?php if(!helper::isZeroDate($case->lastRunDate)) echo substr($case->lastRunDate, 5, 11);?></td>
<td class='<?php echo $case->lastRunResult;?>'><?php if($case->lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?></td>
<td>
<?php
+1 -1
View File
@@ -103,7 +103,7 @@
common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link');
if(common::hasPriv('execution', 'testreport'))
{
echo html::a($this->createLink('execution', 'testreport', "executionID=$executionID&objctType=execution&extra=$task->id"), '<i class="icon-testreport-browse icon-flag"></i>', '', 'class="btn " title="' . $lang->testreport->browse . '" data-app="execution"');
echo html::a($this->createLink('execution', 'testreport', "executionID=$executionID&objctType=execution&extra=$task->id"), '<i class="icon-testreport-browse icon-summary"></i>', '', 'class="btn " title="' . $lang->testreport->browse . '" data-app="execution"');
}
common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list');
common::printIcon('testtask', 'delete', "taskID=$task->id", $task, 'list', 'trash', 'hiddenwin');
+4 -1
View File
@@ -293,14 +293,17 @@ class file extends control
* @param array $files
* @param string $fieldset
* @param object $object
* @param string $method
* @access public
* @return void
*/
public function printFiles($files, $fieldset, $object = null)
public function printFiles($files, $fieldset, $object = null, $method = 'view')
{
$this->view->files = $files;
$this->view->fieldset = $fieldset;
$this->view->object = $object;
if($method == 'view') return $this->display('file', 'viewfiles');
$this->display();
}
+1
View File
@@ -36,6 +36,7 @@ $lang->file->addFile = 'Hinzufügen';
$lang->file->beginUpload = 'Upload';
$lang->file->uploadSuccess = 'Hochgeladen!';
$lang->file->batchExport = 'Export in batches';
$lang->file->downloadFile = 'Download';
$lang->file->pathname = 'Pfadname';
$lang->file->title = 'Titel';
+1
View File
@@ -36,6 +36,7 @@ $lang->file->addFile = 'Add';
$lang->file->beginUpload = 'Click to Upload';
$lang->file->uploadSuccess = 'Uploaded!';
$lang->file->batchExport = 'Export in batches';
$lang->file->downloadFile = 'Download';
$lang->file->pathname = 'Path Name';
$lang->file->title = 'Title';
+1
View File
@@ -36,6 +36,7 @@ $lang->file->addFile = 'Ajouter';
$lang->file->beginUpload = 'Clic pour Charger';
$lang->file->uploadSuccess = 'Chargé !';
$lang->file->batchExport = 'Export in batches';
$lang->file->downloadFile = 'Download';
$lang->file->pathname = 'Nom Chemin';
$lang->file->title = 'Titre';
+1
View File
@@ -36,6 +36,7 @@ $lang->file->addFile = '添加文件';
$lang->file->beginUpload = '开始上传';
$lang->file->uploadSuccess = '上传成功';
$lang->file->batchExport = '分批导出';
$lang->file->downloadFile = '下载';
$lang->file->pathname = '路径';
$lang->file->title = '标题';
-1
View File
@@ -2,7 +2,6 @@
<?php $sessionString = session_name() . '=' . session_id();?>
<?php if($fieldset == 'true'):?>
<div class="detail">
<div class="detail-title"><?php echo $lang->file->common;?> <i class="icon icon-paper-clip icon-sm"></i></div>
<div class="detail-content">
<?php endif;?>
<style>
+135
View File
@@ -0,0 +1,135 @@
<?php if($files):?>
<?php $sessionString = session_name() . '=' . session_id();?>
<?php if($fieldset == 'true'):?>
<div class="detail">
<div class="detail-title"><?php echo $lang->file->common;?> <i class="icon icon-paper-clip icon-sm"></i></div>
<div class="detail-content">
<?php endif;?>
<style>
.files-list>li>a {display: inline; word-wrap: break-word;}
.files-list>li>.right-icon {opacity: 1;}
</style>
<script>
/* Delete a file. */
function deleteFile(fileID)
{
if(!fileID) return;
hiddenwin.location.href = createLink('file', 'delete', 'fileID=' + fileID);
}
/* Download a file, append the mouse to the link. Thus we call decide to open the file in browser no download it. */
function downloadFile(fileID, extension, imageWidth, fileTitle)
{
if(!fileID) return;
var fileTypes = 'txt,jpg,jpeg,gif,png,bmp';
var windowWidth = $(window).width();
var width = (windowWidth > imageWidth) ? ((imageWidth < windowWidth * 0.5) ? windowWidth * 0.5 : imageWidth) : windowWidth;
var checkExtension = fileTitle.lastIndexOf('.' + extension) == (fileTitle.length - extension.length - 1);
var url = createLink('file', 'download', 'fileID=' + fileID + '&mouse=left');
url += url.indexOf('?') >= 0 ? '&' : '?';
url += '<?php echo $sessionString;?>';
if(fileTypes.indexOf(extension) >= 0 && checkExtension && config.onlybody != 'yes')
{
$('<a>').modalTrigger({url: url, type: 'iframe', width: width}).trigger('click');
}
else
{
url = url.replace('?onlybody=yes&', '?');
url = url.replace('?onlybody=yes', '?');
url = url.replace('&onlybody=yes', '');
window.open(url, '_blank');
}
return false;
}
</script>
<ul class="files-list">
<?php
foreach($files as $file)
{
if(common::hasPriv('file', 'download'))
{
$uploadDate = $lang->file->uploadDate . substr($file->addedDate, 0, 10);
$fileTitle = "<i class='icon icon-file-text'></i> &nbsp;" . $file->title;
if(strpos($file->title, ".{$file->extension}") === false && $file->extension != 'txt') $fileTitle .= ".{$file->extension}";
$imageWidth = 0;
if(stripos('jpg|jpeg|gif|png|bmp', $file->extension) !== false)
{
$imageSize = $this->file->getImageSize($file);
$imageWidth = $imageSize ? $imageSize[0] : 0;
}
$fileSize = 0;
/* Show size info. */
if($file->size < 1024)
{
$fileSize = $file->size . 'B';
}
elseif($file->size < 1024 * 1024)
{
$file->size = round($file->size / 1024, 2);
$fileSize = $file->size . 'K';
}
elseif($file->size < 1024 * 1024 * 1024)
{
$file->size = round($file->size / (1024 * 1024), 2);
$fileSize = $file->size . 'M';
}
else
{
$file->size = round($file->size / (1024 * 1024 * 1024), 2);
$fileSize = $file->size . 'G';
}
$downloadLink = $this->createLink('file', 'download', "fileID=$file->id");
$downloadLink .= strpos($downloadLink, '?') === false ? '?' : '&';
$downloadLink .= $sessionString;
echo "<li title='{$uploadDate}'>" . html::a($downloadLink, $fileTitle . " <span class='text-muted'>({$fileSize})</span>", '_blank', "onclick=\"return downloadFile($file->id, '$file->extension', $imageWidth, '$file->title')\"");
$objectType = zget($this->config->file->objectType, $file->objectType);
if(common::hasPriv($objectType, 'edit', $object))
{
echo "<span class='right-icon'>&nbsp; ";
/* Determines whether the file supports preview. */
if($file->extension == 'txt')
{
$extension = 'txt';
if(($postion = strrpos($file->title, '.')) !== false) $extension = substr($file->title, $postion + 1);
if($extension != 'txt') $mode = 'down';
$file->extension = $extension;
}
/* For the open source version of the file judgment. */
if(stripos('txt|jpg|jpeg|gif|png|bmp', $file->extension) !== false)
{
echo html::a($downloadLink, $lang->file->preview, '_blank', "class='text-primary' onclick=\"return downloadFile($file->id, '$file->extension', $imageWidth, '$file->title')\"");
}
/* For the max version of the file judgment. */
if(isset($this->config->file->libreOfficeTurnon) and $this->config->file->libreOfficeTurnon == 1)
{
$officeTypes = 'doc|docx|xls|xlsx|ppt|pptx|pdf';
if(stripos($officeTypes, $file->extension) !== false)
{
echo html::a($downloadLink, $lang->file->preview, '_blank', "class='text-primary' onclick=\"return downloadFile($file->id, '$file->extension', $imageWidth, '$file->title')\"");
}
}
common::printLink('file', 'download', "fileID=$file->id", $lang->file->downloadFile, '_blank', "class='text-primary' title='{$lang->file->downloadFile}'");
common::printLink('file', 'edit', "fileID=$file->id", $lang->file->edit, '', "data-width='400' class='edit iframe text-primary' title='{$lang->file->edit}'");
if(common::hasPriv('file', 'delete')) echo html::a('###', $lang->delete, '', "class='text-primary' onclick='deleteFile($file->id)' title='$lang->delete'");
echo '</span>';
}
echo '</li>';
}
}
?>
</ul>
<?php if($fieldset == 'true'):?>
</div>
</div>
<?php endif;?>
<?php endif;?>
+4
View File
@@ -124,3 +124,7 @@ $config->gitlab->accessLevel['owner'] = 50;
/* Minimum compatible version. */
$config->gitlab->minCompatibleVersion = '9.0';
$config->gitlab->menus['project'] = 'browseProject';
$config->gitlab->menus['group'] = 'browseGroup';
$config->gitlab->menus['user'] = 'browseUser';
+29 -4
View File
@@ -325,8 +325,9 @@ class gitlab extends control
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
}
$groups = $this->gitlab->apiGetGroups($gitlabID, $orderBy);
$adminGroups = $this->gitlab->apiGetGroups($gitlabID, $orderBy, 'owner');
$keyword = fixer::input('post')->setDefault('keyword', '')->get('keyword');
$groups = $this->gitlab->apiGetGroups($gitlabID, $orderBy, '', $keyword);
$adminGroups = $this->gitlab->apiGetGroups($gitlabID, $orderBy, 'owner', $keyword);
$adminGroupIDList = array();
foreach($adminGroups as $group) $adminGroupIDList[] = $group->id;
@@ -337,6 +338,7 @@ class gitlab extends control
$this->view->gitlabGroupList = $groups;
$this->view->adminGroupIDList = $adminGroupIDList;
$this->view->orderBy = $orderBy;
$this->view->keyword = $keyword;
$this->display();
}
@@ -558,11 +560,22 @@ class gitlab extends control
if(!$user->is_admin) $isAdmin = false;
}
$keyword = fixer::input('post')->setDefault('keyword', '')->get('keyword');
$users = $this->gitlab->apiGetUsers($gitlabID, false, $orderBy);
if($keyword)
{
foreach($users as $key => $user)
{
if(strpos($user->realname, $keyword) === false) unset($users[$key]);
}
}
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseUser;
$this->view->gitlabID = $gitlabID;
$this->view->gitlabUserList = $this->gitlab->apiGetUsers($gitlabID, false, $orderBy);
$this->view->gitlabUserList = $users;
$this->view->orderBy = $orderBy;
$this->view->isAdmin = $isAdmin;
$this->view->keyword = $keyword;
$this->display();
}
@@ -583,10 +596,22 @@ class gitlab extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseUser', "gitlabID=$gitlabID")));
}
$userPairs = $this->loadModel('user')->getPairs('noclosed|noletter');
$users = $this->loadModel('user')->getList();
$bindedUsers = $this->gitlab->getUserAccountIdPairs($gitlabID);
$userPairs = array('' => '');
$userInfos = array();
foreach($users as $key => $user)
{
if(!isset($bindedUsers[$user->account]))
{
$userPairs[$user->account] = $user->realname;
$userInfos[$user->account] = $user;
}
}
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->user->create;
$this->view->userPairs = $userPairs;
$this->view->users = $userInfos;
$this->view->gitlabID = $gitlabID;
$this->display();
}
-17
View File
@@ -1,17 +0,0 @@
$(document).ready(function()
{
$('#projectSearch').click(function()
{
triggerSearch();
});
$('#keyword').keypress(function(event)
{
if(event.which == 13) triggerSearch();
})
});
function triggerSearch()
{
$("#gitlabprojectForm").submit();
}
+19 -1
View File
@@ -17,4 +17,22 @@ function setAvatar()
$(".avatar img").attr("src", window.URL.createObjectURL(files[0]));
$(".avatar").removeClass('hidden');
});
}
}
$(document).ready(function()
{
$('#gitlabSearch').click(function()
{
triggerSearch();
});
$('#keyword').keypress(function(event)
{
if(event.which == 13) triggerSearch();
})
});
function triggerSearch()
{
$("#gitlabForm").submit();
}
+17 -1
View File
@@ -1,4 +1,20 @@
$(document).ready(function()
{
setAvatar();
});
$('#account').change(function()
{
var account = $(this).val();
var user = users[account];
var name = '';
var email = '';
if(account && user)
{
name = user.realname;
account = user.account;
email = user.email;
}
$('#name').val(name);
$('#username').val(account);
$('#email').val(email);
})
});
+6 -5
View File
@@ -24,14 +24,14 @@ $lang->gitlab->lastUpdate = 'Last Update';
$lang->gitlab->confirmAddWebhook = 'Are you sure about creating Webhook?';
$lang->gitlab->addWebhookSuccess = 'Webhook created successfully';
$lang->gitlab->failCreateWebhook = 'Failed to create Webhook, please view the log';
$lang->gitlab->placeholderSearch = 'Project name';
$lang->gitlab->placeholderSearch = 'Enter name';
$lang->gitlab->browseAction = 'GitLab List';
$lang->gitlab->deleteAction = 'Delete GitLab';
$lang->gitlab->gitlabProject = "GitLab Project";
$lang->gitlab->browseProject = "GitLab Project List";
$lang->gitlab->browseUser = "User List";
$lang->gitlab->browseGroup = "Group List";
$lang->gitlab->browseProject = "Project";
$lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
@@ -62,12 +62,13 @@ $lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "GitLab Server";
$lang->gitlab->name = "Server Name";
$lang->gitlab->url = 'Server URL';
$lang->gitlab->token = 'Token';
$lang->gitlab->defaultProject = 'Default Project';
$lang->gitlab->private = 'MD5 Verify';
$lang->gitlab->server = "Server List";
$lang->gitlab->lblCreate = 'Create GitLab Server';
$lang->gitlab->desc = 'Description';
$lang->gitlab->tokenFirst = 'When the Token is not empty, the Token will be used first';
+6 -5
View File
@@ -24,14 +24,14 @@ $lang->gitlab->lastUpdate = 'Last Update';
$lang->gitlab->confirmAddWebhook = 'Are you sure about creating Webhook?';
$lang->gitlab->addWebhookSuccess = 'Webhook created successfully';
$lang->gitlab->failCreateWebhook = 'Failed to create Webhook, please view the log';
$lang->gitlab->placeholderSearch = 'Project name';
$lang->gitlab->placeholderSearch = 'Enter name';
$lang->gitlab->browseAction = 'GitLab List';
$lang->gitlab->deleteAction = 'Delete GitLab';
$lang->gitlab->gitlabProject = "GitLab Project";
$lang->gitlab->browseProject = "GitLab Project List";
$lang->gitlab->browseUser = "User List";
$lang->gitlab->browseGroup = "Group List";
$lang->gitlab->browseProject = "Project";
$lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
@@ -62,12 +62,13 @@ $lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "GitLab Server";
$lang->gitlab->name = "Server Name";
$lang->gitlab->url = 'Server URL';
$lang->gitlab->token = 'Token';
$lang->gitlab->defaultProject = 'Default Project';
$lang->gitlab->private = 'MD5 Verify';
$lang->gitlab->server = "Server List";
$lang->gitlab->lblCreate = 'Create GitLab Server';
$lang->gitlab->desc = 'Description';
$lang->gitlab->tokenFirst = 'When the Token is not empty, the Token will be used first';
+6 -5
View File
@@ -24,14 +24,14 @@ $lang->gitlab->lastUpdate = 'Last Update';
$lang->gitlab->confirmAddWebhook = 'Are you sure about creating Webhook?';
$lang->gitlab->addWebhookSuccess = 'Webhook created successfully';
$lang->gitlab->failCreateWebhook = 'Failed to create Webhook, please view the log';
$lang->gitlab->placeholderSearch = 'Project name';
$lang->gitlab->placeholderSearch = 'Enter name';
$lang->gitlab->browseAction = 'GitLab List';
$lang->gitlab->deleteAction = 'Delete GitLab';
$lang->gitlab->gitlabProject = "GitLab Project";
$lang->gitlab->browseProject = "GitLab Project List";
$lang->gitlab->browseUser = "User List";
$lang->gitlab->browseGroup = "Group List";
$lang->gitlab->browseProject = "Project";
$lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
@@ -62,12 +62,13 @@ $lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "GitLab Server";
$lang->gitlab->name = "Server Name";
$lang->gitlab->url = 'Server URL';
$lang->gitlab->token = 'Token';
$lang->gitlab->defaultProject = 'Default Project';
$lang->gitlab->private = 'MD5 Verify';
$lang->gitlab->server = "Server List";
$lang->gitlab->lblCreate = 'Create GitLab Server';
$lang->gitlab->desc = 'Description';
$lang->gitlab->tokenFirst = 'When the Token is not empty, the Token will be used first';
+239
View File
@@ -0,0 +1,239 @@
<?php
$lang->gitlab = new stdclass;
$lang->gitlab->common = 'GitLab';
$lang->gitlab->browse = 'GitLab Browse';
$lang->gitlab->search = 'Search';
$lang->gitlab->create = 'Create GitLab';
$lang->gitlab->edit = 'Edit GitLab';
$lang->gitlab->view = 'View GitLab';
$lang->gitlab->bindUser = 'Bind User';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = 'Import Product';
$lang->gitlab->importIssue = 'Import Issue';
$lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';
$lang->gitlab->bindDynamic = '%s and Zentao user %s';
$lang->gitlab->serverFail = 'Connect to GitLab server failed, please check the GitLab server.';
$lang->gitlab->lastUpdate = 'Last Update';
$lang->gitlab->confirmAddWebhook = 'Are you sure about creating Webhook?';
$lang->gitlab->addWebhookSuccess = 'Webhook created successfully';
$lang->gitlab->failCreateWebhook = 'Failed to create Webhook, please view the log';
$lang->gitlab->placeholderSearch = 'Enter name';
$lang->gitlab->browseAction = 'GitLab List';
$lang->gitlab->deleteAction = 'Delete GitLab';
$lang->gitlab->gitlabProject = "GitLab Project";
$lang->gitlab->browseProject = "Project";
$lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
$lang->gitlab->gitlabIssue = "GitLab Issue";
$lang->gitlab->zentaoProduct = 'Zentao Product';
$lang->gitlab->objectType = 'Type'; // task, bug, story
$lang->gitlab->manageProjectMembers = 'Manage project member';
$lang->gitlab->createProject = 'Create GitLab project';
$lang->gitlab->editProject = 'Eidt GitLab project';
$lang->gitlab->deleteProject = 'Delete GitLab project';
$lang->gitlab->createGroup = 'Create group';
$lang->gitlab->editGroup = 'Edit group';
$lang->gitlab->deleteGroup = 'Delete group';
$lang->gitlab->createUser = 'Create user';
$lang->gitlab->editUser = 'Edit user';
$lang->gitlab->deleteUser = 'Delete user';
$lang->gitlab->createBranch = 'Add branch';
$lang->gitlab->manageGroupMembers = 'Manage group member';
$lang->gitlab->createWebhook = 'Create Webhook';
$lang->gitlab->browseBranchPriv = 'Protect branch';
$lang->gitlab->createBranchPriv = 'Cerate branch protected';
$lang->gitlab->editBranchPriv = 'Edit branch protected';
$lang->gitlab->deleteBranchPriv = 'Delete branch protected';
$lang->gitlab->createTag = 'Create Tag';
$lang->gitlab->deleteTag = 'Delete tag';
$lang->gitlab->createTagPriv = 'Create tag protected';
$lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "Server Name";
$lang->gitlab->url = 'Server URL';
$lang->gitlab->token = 'Token';
$lang->gitlab->defaultProject = 'Default Project';
$lang->gitlab->private = 'MD5 Verify';
$lang->gitlab->server = "Server List";
$lang->gitlab->lblCreate = 'Create GitLab Server';
$lang->gitlab->desc = 'Description';
$lang->gitlab->tokenFirst = 'When the Token is not empty, the Token will be used first';
$lang->gitlab->tips = 'When using a password, please disable the "Prevent cross-site request forgery" option in the GitLab global security settings.';
$lang->gitlab->emptyError = " cannot be empty";
$lang->gitlab->createSuccess = "Create success";
$lang->gitlab->mustBindUser = 'You have not registered the GitLab account, please contact the administrator to register.';
$lang->gitlab->noAccess = 'Permission denied';
$lang->gitlab->notCompatible = 'The current GitLab version is not compatible with ZenTao, please upgrade the GitLab version and try again';
$lang->gitlab->deleted = 'Deleted';
$lang->gitlab->placeholder = new stdclass;
$lang->gitlab->placeholder->name = '';
$lang->gitlab->placeholder->url = "Please fill in the access address of the GitLab Server homepage, as: https://gitlab.zentao.net.";
$lang->gitlab->placeholder->token = "Please fill in the access token of an account with root privileges.";
$lang->gitlab->placeholder->projectPath = "It should contain only letters, digits, underscore, hyphen and period. It should not start with hypen, or end with .git or .atom.";
$lang->gitlab->noImportableIssues = "There are currently no issues available for import.";
$lang->gitlab->tokenError = "The current token is not root rights.";
$lang->gitlab->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in GitLab.";
$lang->gitlab->hostError = "So the current GitLab server address is invalid or the current GitLab version is not compatible with ZenTao, please confirm that the current server can be accessed or contact the administrator to upgrade the GitLab version to %s or above and try again.";
$lang->gitlab->bindUserError = "Can not bind users repeatedly %s";
$lang->gitlab->importIssueError = "The execution to which this issue belongs is not selected.";
$lang->gitlab->importIssueWarn = "There is a problem of import failure, you can try to import again.";
$lang->gitlab->accessLevels[10] = 'Guest';
$lang->gitlab->accessLevels[20] = 'Reporter';
$lang->gitlab->accessLevels[30] = 'Developer';
$lang->gitlab->accessLevels[40] = 'Maintainer';
$lang->gitlab->accessLevels[50] = 'Owner';
$lang->gitlab->apiError[0] = 'internal is not allowed in a private group.';
$lang->gitlab->apiError[1] = 'public is not allowed in a private group.';
$lang->gitlab->apiError[2] = 'is too short (minimum is 8 characters)';
$lang->gitlab->apiError[3] = "can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'";
$lang->gitlab->apiError[4] = 'Branch already exists';
$lang->gitlab->apiError[5] = 'Failed to save group {:path=>["has already been taken"]}';
$lang->gitlab->apiError[6] = '403 Forbidden';
$lang->gitlab->errorLang[0] = 'You cannot set Internal as its Visibility Level, if it is private in GitLab.';
$lang->gitlab->errorLang[1] = 'You cannot set Public as its Visibility Level, if it is private in GitLab.';
$lang->gitlab->errorLang[2] = 'Password is too short (minimum is 8 characters)';
$lang->gitlab->errorLang[3] = 'It should contain only letters, digits, underscore, hyphen and period. It should not start with hypen, or end with .git or .atom.';
$lang->gitlab->errorLang[4] = 'Branch already exists.';
$lang->gitlab->errorLang[5] = 'Failed to save group, path has already been taken.';
$lang->gitlab->errorLang[6] = $lang->gitlab->noAccess;
$lang->gitlab->project = new stdclass;
$lang->gitlab->project->id = "Project ID";
$lang->gitlab->project->name = "Project name";
$lang->gitlab->project->create = "Create GitLab project";
$lang->gitlab->project->edit = "Edit GitLab project";
$lang->gitlab->project->url = "Project URL";
$lang->gitlab->project->path = "Project slug";
$lang->gitlab->project->description = "Project description";
$lang->gitlab->project->visibility = "Visibility Level";
$lang->gitlab->project->visibilityList['private'] = "Private(Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group)";
$lang->gitlab->project->visibilityList['internal'] = "Internal(The project can be accessed by any logged in user except external users)";
$lang->gitlab->project->visibilityList['public'] = "Public(The project can be accessed without any authentication)";
$lang->gitlab->project->star = "Stars";
$lang->gitlab->project->fork = "Forks";
$lang->gitlab->project->mergeRequests = "Merge Requests";
$lang->gitlab->project->issues = "Issues";
$lang->gitlab->project->tagList = "Topics";
$lang->gitlab->project->tagListTips = "Separate topics with commas.";
$lang->gitlab->project->emptyNameError = "Project name cannot be empty.";
$lang->gitlab->project->emptyPathError = "Project slug cannot be empty.";
$lang->gitlab->project->confirmDelete = 'Do you want to delete this GitLab project?';
$lang->gitlab->project->notbindedError = 'GitLab user has not been bound, unable to modify permissions!';
$lang->gitlab->project->publicTip = 'The visible status of the current project will be modified to public, and the project can be accessed without any authentication in GitLab. ';
$lang->gitlab->user = new stdclass;
$lang->gitlab->user->id = "User ID";
$lang->gitlab->user->name = "Name";
$lang->gitlab->user->username = "Username";
$lang->gitlab->user->email = "Email";
$lang->gitlab->user->password = "Password";
$lang->gitlab->user->passwordRepeat = "Repeat Password";
$lang->gitlab->user->projectsLimit = "Projects limit";
$lang->gitlab->user->canCreateGroup = "Can create group";
$lang->gitlab->user->external = "External";
$lang->gitlab->user->externalTip = "External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects, groups, or personal snippets.";
$lang->gitlab->user->bind = "Zentao user";
$lang->gitlab->user->avatar = "Avatar";
$lang->gitlab->user->skype = "Skype";
$lang->gitlab->user->linkedin = "Linkedin";
$lang->gitlab->user->twitter = "Twitter";
$lang->gitlab->user->websiteUrl = "Website url";
$lang->gitlab->user->note = "Note";
$lang->gitlab->user->createOn = "Created on";
$lang->gitlab->user->lastActivity = "Last activity";
$lang->gitlab->user->create = "Create GitLab user";
$lang->gitlab->user->edit = "Edit GitLab user";
$lang->gitlab->user->emptyError = "cannot be empty";
$lang->gitlab->user->passwordError = "The second password is inconsistent!";
$lang->gitlab->user->bindError = "The user has been bound!";
$lang->gitlab->user->confirmDelete = 'Do you want to delete this GitLab user?';
$lang->gitlab->group = new stdclass;
$lang->gitlab->group->id = "Group ID";
$lang->gitlab->group->name = "Group name";
$lang->gitlab->group->path = "Group URL";
$lang->gitlab->group->pathTip = "Changing group URL can have unintended side effects.";
$lang->gitlab->group->description = "Group description";
$lang->gitlab->group->avatar = "Group avatar";
$lang->gitlab->group->avatarTip = 'Max file size is 200 KB.';
$lang->gitlab->group->visibility = "Visibility level";
$lang->gitlab->group->visibilityList['private'] = "Private(The group and its projects can only be viewed by members)";
$lang->gitlab->group->visibilityList['internal'] = "Internal(The group and any internal projects can be viewed by any logged in user except external users)";
$lang->gitlab->group->visibilityList['public'] = "Public(The group and any public projects can be viewed without any authentication.)";
$lang->gitlab->group->permission = 'Permission';
$lang->gitlab->group->requestAccessEnabledTip = "Allow users to request access (if visibility is public or internal)";
$lang->gitlab->group->lfsEnabled = 'Large File Storage';
$lang->gitlab->group->lfsEnabledTip = "Allow projects within this group to use Git LFS(This setting can be overridden in each project)";
$lang->gitlab->group->projectCreationLevel = "Allowed to create projects";
$lang->gitlab->group->projectCreationLevelList['noone'] = "No one";
$lang->gitlab->group->projectCreationLevelList['maintainer'] = "Maintainers";
$lang->gitlab->group->projectCreationLevelList['developer'] = "Developers + Maintainers";
$lang->gitlab->group->subgroupCreationLevel = "Allowed to create projects";
$lang->gitlab->group->subgroupCreationLevelList['owner'] = "Owners";
$lang->gitlab->group->subgroupCreationLevelList['maintainer'] = "Maintainers";
$lang->gitlab->group->create = "Create Group";
$lang->gitlab->group->edit = "Edit Group";
$lang->gitlab->group->createOn = "Created on";
$lang->gitlab->group->members = "Group Members";
$lang->gitlab->group->confirmDelete = 'Do you want to delete this GitLab group?';
$lang->gitlab->group->emptyError = "cannot be empty";
$lang->gitlab->group->manageMembers = 'Manage Group Members';
$lang->gitlab->group->memberName = 'Account';
$lang->gitlab->group->memberAccessLevel = 'Access Level';
$lang->gitlab->group->memberExpiresAt = 'Expiration time';
$lang->gitlab->group->repeatError = "Group members cannot be added repeatedly";
$lang->gitlab->group->publicTip = 'The visible status of the current group will be modified to public, and the group can be accessed without any authentication in GitLab. ';
$lang->gitlab->branch = new stdclass();
$lang->gitlab->branch->name = 'Branch name';
$lang->gitlab->branch->from = 'Create from';
$lang->gitlab->branch->create = 'Create';
$lang->gitlab->branch->lastCommitter = 'Last Committer';
$lang->gitlab->branch->lastCommittedDate = 'Last Committed Date';
$lang->gitlab->branch->accessLevel = "Branch protection list";
$lang->gitlab->branch->mergeAllowed = "Merge Allowed";
$lang->gitlab->branch->pushAllowed = "Push Allowed";
$lang->gitlab->branch->placeholderSearch = "Branch name";
$lang->gitlab->branch->placeholderSelect = "Branch name";
$lang->gitlab->branch->confirmDelete = 'Branch will be writable for developers. Are you sure?';
$lang->gitlab->branch->branchCreationLevelList[40] = "Maintainers";
$lang->gitlab->branch->branchCreationLevelList[30] = "Developers + Maintainers";
$lang->gitlab->branch->branchCreationLevelList[0] = "No one";
$lang->gitlab->branch->emptyPrivNameError = "Branch cannot be empty.";
$lang->gitlab->branch->issetPrivNameError = "The protection branch already exists";
$lang->gitlab->tag = new stdclass();
$lang->gitlab->tag->name = 'Tag name';
$lang->gitlab->tag->ref = 'Create from';
$lang->gitlab->tag->lastCommitter = 'Last Committer';
$lang->gitlab->tag->lastCommittedDate = 'Last Committed Date';
$lang->gitlab->tag->placeholderSearch = "Enter branch tag";
$lang->gitlab->tag->message = 'Message';
$lang->gitlab->tag->emptyNameError = "Name cannot be empty.";
$lang->gitlab->tag->emptyRefError = "Create from cannot be empty.";
$lang->gitlab->tag->issetNameError = "The tag already exists";
$lang->gitlab->tag->confirmDelete = 'Do you want to delete this GitLab tag?';
$lang->gitlab->tag->protected = 'Protected';
$lang->gitlab->tag->accessLevel = 'Allow creation';
$lang->gitlab->tag->protectConfirmDel = 'Do you want to delete this GitLab tag protected?';
$lang->gitlab->tag->emptyPrivNameError = 'Tag cannot be empty.';
$lang->gitlab->tag->issetPrivNameError = 'The protection tag already exists.';
+6 -5
View File
@@ -24,14 +24,14 @@ $lang->gitlab->lastUpdate = '最后更新';
$lang->gitlab->confirmAddWebhook = '您确定创建Webhook吗?';
$lang->gitlab->addWebhookSuccess = 'Webhook创建成功';
$lang->gitlab->failCreateWebhook = 'Webhook创建失败,请查看日志';
$lang->gitlab->placeholderSearch = '请输入项目名称';
$lang->gitlab->placeholderSearch = '请输入名称';
$lang->gitlab->browseAction = 'GitLab列表';
$lang->gitlab->deleteAction = '删除GitLab';
$lang->gitlab->gitlabProject = "{$lang->gitlab->common}项目";
$lang->gitlab->browseProject = "{$lang->gitlab->common}项目列表";
$lang->gitlab->browseUser = "用户列表";
$lang->gitlab->browseGroup = "群组列表";
$lang->gitlab->browseProject = "项目";
$lang->gitlab->browseUser = "用户";
$lang->gitlab->browseGroup = "群组";
$lang->gitlab->browseBranch = "GitLab分支列表";
$lang->gitlab->browseTag = "GitLab标签列表";
$lang->gitlab->browseTagPriv = "GitLab标签保护列表";
@@ -62,12 +62,13 @@ $lang->gitlab->editTagPriv = '编辑标签保护';
$lang->gitlab->deleteTagPriv = '删除标签保护';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "{$lang->gitlab->common}服务器";
$lang->gitlab->name = "服务器名称";
$lang->gitlab->url = '服务器地址';
$lang->gitlab->token = 'Token';
$lang->gitlab->defaultProject = '默认项目';
$lang->gitlab->private = 'MD5验证';
$lang->gitlab->server = "服务器列表";
$lang->gitlab->lblCreate = '添加GitLab服务器';
$lang->gitlab->desc = '描述';
$lang->gitlab->tokenFirst = 'Token不为空时,优先使用Token。';
+43 -1
View File
@@ -601,10 +601,11 @@ class gitlabModel extends model
* @param int $gitlabID
* @param string $orderBy
* @param string $minRole
* @param string $keyword
* @access public
* @return object
*/
public function apiGetGroups($gitlabID, $orderBy = 'id_desc', $minRole = '')
public function apiGetGroups($gitlabID, $orderBy = 'id_desc', $minRole = '', $keyword = '')
{
$apiRoot = $this->getApiRoot($gitlabID);
$url = sprintf($apiRoot, "/groups");
@@ -617,6 +618,8 @@ class gitlabModel extends model
$url .= '&min_access_level=' . $this->config->gitlab->accessLevel[$minRole];
}
if($keyword) $url .= '&search=' . urlencode($keyword);
$order = 'id';
$sort = 'desc';
if(strpos($orderBy, '_') !== false) list($order, $sort) = explode('_', $orderBy);
@@ -2854,4 +2857,43 @@ class gitlabModel extends model
$apiRoot .= '&sudo=' . $users[0]->id;
return $this->apiGet($apiRoot, '/user');
}
/**
* Get gitlab menu.
*
* @param int $gitlabID
* @param string $type
* @access public
* @return void
*/
public function getGitlabMenu($gitlabID = 0, $type = 'project')
{
$html = '<div class="btn-toolbar pull-left">';
/* Gitlab server list. */
$gitlabs = $this->getPairs();
$html .= "<div class='btn-group'>";
$tips = $gitlabID >0 ? zget($gitlabs, $gitlabID, $this->lang->gitlab->server) : $this->lang->gitlab->server;
$html .= html::a('javascript:;', $tips . " <span class='caret'></span>", '', "data-toggle='dropdown' class='btn btn-link'");
$html .= "<ul class='dropdown-menu'>";
foreach($gitlabs as $id => $gitlab)
{
$html .= '<li' . ($gitlabID == $id ? " class='active'" : '') . '>';
$html .= html::a(helper::createLink('gitlab', zget($this->config->gitlab->menus, $type, 'project'), "gitlabID=$id"), $gitlab);
}
$html .= '</ul></div>';
/* Other route. */
foreach($this->config->gitlab->menus as $key => $method)
{
$lang = 'browse' . ucwords($key);
$title = $this->lang->gitlab->$lang;
$label = "<span class='text'>$title</span>";
$active = $key == $type ? 'btn-active-text' : '';
$html .= html::a(inlink($method, "gitlabID=$gitlabID"), $label, '', "id='{$key}' class='btn btn-link $active' title='$title'");
}
$html .= '</div>';
return $html;
}
}
+6 -6
View File
@@ -12,6 +12,9 @@
?>
<?php include '../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php echo html::a($this->createLink('gitlab', 'browse'), "<span class='text'>{$lang->gitlab->server}</span>", '', "class='btn btn-link btn-active-text'");?>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('gitlab', 'create')) common::printLink('gitlab', 'create', "", "<i class='icon icon-plus'></i> " . $lang->gitlab->create, '', "class='btn btn-primary'");?>
</div>
@@ -35,7 +38,7 @@
<th class='c-id text-center'><?php common::printOrderLink('id', $orderBy, $vars, $lang->gitlab->id);?></th>
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->gitlab->name);?></th>
<th class='text-left'><?php common::printOrderLink('url', $orderBy, $vars, $lang->gitlab->url);?></th>
<th class='c-actions-6'><?php echo $lang->actions;?></th>
<th class='c-actions-3'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -43,8 +46,8 @@
<tr class='text' title='<?php if(!$gitlab->isAdminToken) echo $lang->gitlab->tokenLimit;?>'>
<td class='text-center'><?php echo $id;?></td>
<td class='text-c-name' title='<?php echo $gitlab->name;?>'>
<?php if(common::hasPriv('gitlab', 'view')):?>
<a class="iframe" href="<?php echo $this->createLink('gitlab', 'view', "id=$id", '', true); ?>"><?php echo $gitlab->name;?></a>
<?php if(common::hasPriv('gitlab', 'browseProject')):?>
<a href="<?php echo $this->createLink('gitlab', 'browseProject', "gitlabID=$id"); ?>"><?php echo $gitlab->name;?></a>
<?php else:?>
<?php echo $gitlab->name;?>
<?php endif;?>
@@ -54,10 +57,7 @@
<?php
$disabled = !empty($gitlab->isAdminToken) ? '' : 'disabled';
$notBind = $gitlab->isBindUser ? '' : 'disabled';
common::printLink('gitlab', 'browseProject', "gitlabID=$id", "<i class='icon icon-list-box'></i> ", '',"title='{$lang->gitlab->browseProject}' class='btn {$notBind}'");
common::printLink('gitlab', 'browseGroup', "gitlabID=$id", "<i class='icon icon-groups'></i> ", '', "title='{$lang->gitlab->browseGroup}' class='btn {$notBind}'");
common::printLink('gitlab', 'edit', "gitlabID=$id", "<i class='icon icon-edit'></i> ", '',"title='{$lang->gitlab->edit}' class='btn btn-primary'");
common::printLink('gitlab', 'browseUser', "gitlabID=$id", "<i class='icon icon-person'></i> ", '', "title='{$lang->gitlab->browseUser}' class='btn {$disabled} {$notBind}' ,'disabled'");
common::printLink('gitlab', 'bindUser', "id=$id", "<i class='icon icon-link'></i> ", '', "title='{$lang->gitlab->bindUser}' class='btn {$disabled} {$notBind}' ,'disabled'");
if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'delete', "gitlabID=$id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->gitlab->delete}' class='btn'");
?>
+6 -2
View File
@@ -12,8 +12,12 @@
?>
<?php include '../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class='pull-left'>
<?php echo html::linkButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, $this->createLink('gitlab', 'browse'), 'self', '','btn btn-secondary');?>
<?php echo $this->gitlab->getGitlabMenu($gitlabID, 'group');?>
<div class="btn-toolbar pull-left">
<form id='gitlabForm' method='post'>
<?php echo html::input('keyword', $keyword, "class='form-control' placeholder='{$lang->gitlab->placeholderSearch}' style='display: inline-block;width:auto;margin:0 10px'");?>
<a id="gitlabSearch" class="btn btn-primary"><?php echo $lang->gitlab->search?></a>
</form>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('gitlab', 'create')) common::printLink('gitlab', 'createGroup', "gitlabID=$gitlabID", "<i class='icon icon-plus'></i> " . $lang->gitlab->group->create, '', "class='btn btn-primary'");?>
+5 -14
View File
@@ -14,19 +14,12 @@
<?php js::set('vars', "keyword=%s&orderBy=id_desc&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID=1")?>
<?php js::set('gitlabID', $gitlabID)?>
<div id="mainMenu" class="clearfix">
<div class='pull-left'>
<?php echo html::a($this->createLink('gitlab', 'browse'), "<i class='icon icon-back icon-sm'></i> " . $lang->goback, '', "class='btn btn-secondary'");?>
</div>
<div id="sidebarHeader">
<div class="title"><?php echo $this->lang->gitlab->common . ':' . $gitlab->name; ?></div>
</div>
<?php echo $this->gitlab->getGitlabMenu($gitlabID, 'project');?>
<div class="btn-toolbar pull-left">
<div>
<form id='gitlabprojectForm' method='post'>
<form id='gitlabForm' method='post'>
<?php echo html::input('keyword', $keyword, "class='form-control' placeholder='{$lang->gitlab->placeholderSearch}' style='display: inline-block;width:auto;margin:0 10px'");?>
<a id="projectSearch" class="btn btn-primary"><?php echo $lang->gitlab->search?></a>
</form>
</div>
<a id="gitlabSearch" class="btn btn-primary"><?php echo $lang->gitlab->search?></a>
</form>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('gitlab', 'createProject')) common::printLink('gitlab', 'createProject', "gitlabID=$gitlabID", "<i class='icon icon-plus'></i> " . $lang->gitlab->project->create, '', "class='btn btn-primary'");?>
@@ -52,7 +45,7 @@
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->gitlab->project->name);?></th>
<th class='text-left'></th>
<th class='text-left'><?php echo $lang->gitlab->lastUpdate;?></th>
<th class='c-actions-6'><?php echo $lang->actions;?></th>
<th class='c-actions-4'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -70,9 +63,7 @@
$maintainerClass = $gitlabProject->isMaintainer ? '' : 'disabled';
$ownerClass = $gitlabProject->adminer ? '' : 'disabled';
$emptyBranchClass = $gitlabProject->default_branch ? '' : 'disabled';
common::printLink('gitlab', 'browseBranch', "gitlabID=$gitlabID&projectID=$gitlabProject->id", "<i class='icon icon-treemap'></i> ", '', "title='{$lang->gitlab->browseBranch}' class='btn {$emptyBranchClass}'");
common::printLink('gitlab', 'browseBranchPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", "<i class='icon icon-branch-lock'></i> ", '', "title='{$lang->gitlab->branch->accessLevel}' class='btn {$maintainerClass} {$emptyBranchClass}'");
common::printLink('gitlab', 'browseTag', "gitlabID=$gitlabID&projectID=$gitlabProject->id", "<i class='icon icon-tag'></i> ", '', "title='{$lang->gitlab->browseTag}' class='btn {$emptyBranchClass}'");
common::printLink('gitlab', 'browseTagPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", "<i class='icon icon-tag-lock'></i> ", '', "title='{$lang->gitlab->browseTagPriv}' class='btn {$maintainerClass} {$emptyBranchClass}'");
common::printLink('gitlab', 'editProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id", "<i class='icon icon-edit'></i> ", '', "title='{$lang->gitlab->project->edit}' class='btn {$ownerClass}'");
if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'deleteProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->gitlab->deleteProject}' class='btn {$ownerClass}'");
+6 -2
View File
@@ -12,8 +12,12 @@
?>
<?php include '../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class='pull-left'>
<?php echo html::linkButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, $this->createLink('gitlab', 'browse'), 'self', '','btn btn-secondary');?>
<?php echo $this->gitlab->getGitlabMenu($gitlabID, 'user');?>
<div class="btn-toolbar pull-left">
<form id='gitlabForm' method='post'>
<?php echo html::input('keyword', $keyword, "class='form-control' placeholder='{$lang->gitlab->placeholderSearch}' style='display: inline-block;width:auto;margin:0 10px'");?>
<a id="gitlabSearch" class="btn btn-primary"><?php echo $lang->gitlab->search?></a>
</form>
</div>
<div class="btn-toolbar pull-right">
<?php common::printLink('gitlab', 'createUser', "gitlabID=$gitlabID", "<i class='icon icon-plus'></i> " . $lang->gitlab->user->create, '', "class='btn btn-primary'");?>
+1
View File
@@ -11,6 +11,7 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('users', $users);?>
<div id='mainContent' class='main-row'>
<div class='main-col main-content'>
<div class='center-block'>
+4
View File
@@ -735,6 +735,8 @@ $lang->resource->execution->bug = 'bug';
$lang->resource->execution->testreport = 'testreport';
$lang->resource->execution->burn = 'burn';
$lang->resource->execution->computeBurn = 'computeBurnAction';
$lang->resource->execution->cfd = 'CFD';
$lang->resource->execution->computeCFD = 'computeCFD';
$lang->resource->execution->fixFirst = 'fixFirst';
$lang->resource->execution->burnData = 'burnData';
$lang->resource->execution->team = 'teamAction';
@@ -793,6 +795,8 @@ $lang->execution->methodOrder[115] = 'testtask';
$lang->execution->methodOrder[120] = 'testreport';
$lang->execution->methodOrder[125] = 'burn';
$lang->execution->methodOrder[130] = 'computeBurn';
$lang->execution->methodOrder[132] = 'cfd';
$lang->execution->methodOrder[133] = 'computeCFD';
$lang->execution->methodOrder[135] = 'fixFirst';
$lang->execution->methodOrder[140] = 'burnData';
$lang->execution->methodOrder[145] = 'team';
+1
View File
@@ -50,6 +50,7 @@ body.menu-hide {padding-left: 0;}
.menu-hide #apps {left: 40px;}
.app-container.loading:before {background-color: rgba(0,0,0,.1);}
.app-container.loading:before, .app-container.loading::after {transition-delay: 3s;}
.app-container.loading.open-from-hidden {transition: 0s;}
#appsBar {position: fixed; left: 96px; bottom: 0; right: 0; height: 40px; z-index: 1012; background: #fff; border-top: 1px solid #eff1f7;}
.menu-hide #appsBar {left: 40px;}
+5 -1
View File
@@ -264,7 +264,11 @@
}
/* Show page app and update iframe source */
if(url) reloadApp(appCode, url, true);
if (url)
{
app.$app.toggleClass('open-from-hidden', app.$app.is(':hidden'))
reloadApp(appCode, url, true);
}
app.zIndex = openedAppZIndex++;
app.$app.show().css('z-index', app.zIndex);
+1
View File
@@ -20,6 +20,7 @@ $lang->jenkins->lblCreate = 'Create Jenkins Server';
$lang->jenkins->desc = 'Description';
$lang->jenkins->tokenFirst = 'Use token if not empty.';
$lang->jenkins->tips = 'Cancel "Prevent Cross Site Request Forgery exploits" when using password.';
$lang->jenkins->serverList = 'Server List';
$lang->jenkins->error = new stdclass();
$lang->jenkins->error->linkedJob = 'Failed. This jenkins has associated with the compile.';
+1
View File
@@ -20,6 +20,7 @@ $lang->jenkins->lblCreate = 'Create Jenkins Server';
$lang->jenkins->desc = 'Description';
$lang->jenkins->tokenFirst = 'Use token if not empty.';
$lang->jenkins->tips = 'Cancel "Prevent Cross Site Request Forgery exploits" when using password.';
$lang->jenkins->serverList = 'Server List';
$lang->jenkins->error = new stdclass();
$lang->jenkins->error->linkedJob = 'Failed. This jenkins has associated with the compile.';
+1
View File
@@ -20,6 +20,7 @@ $lang->jenkins->lblCreate = 'Cr閑r Serveur Jenkins';
$lang->jenkins->desc = 'Description';
$lang->jenkins->tokenFirst = 'Utiliser un Token si non vide.';
$lang->jenkins->tips = 'Cancel "Prevent Cross Site Request Forgery exploits" when using password.';
$lang->jenkins->serverList = 'Server List';
$lang->jenkins->error = new stdclass();
$lang->jenkins->error->linkedJob = 'Failed. This jenkins has associated with the compile.';
+1
View File
@@ -17,3 +17,4 @@ $lang->jenkins->lblCreate = 'Tạo Jenkins Server';
$lang->jenkins->desc = 'Mô tả';
$lang->jenkins->tokenFirst = 'Sử dụng token nếu không trống.';
$lang->jenkins->tips = 'Hủy "Ngăn chặn khai thác yêu cầu trang web giả mạo" khi sử dụng mật khẩu.';
$lang->jenkins->serverList = 'Server List';
+1
View File
@@ -20,6 +20,7 @@ $lang->jenkins->lblCreate = '添加Jenkins服务器';
$lang->jenkins->desc = '描述';
$lang->jenkins->tokenFirst = 'Token不为空时,优先使用Token。';
$lang->jenkins->tips = '使用密码时,请在Jenkins全局安全设置中禁用"防止跨站点请求伪造"选项。';
$lang->jenkins->serverList = '服务器列表';
$lang->jenkins->error = new stdclass();
$lang->jenkins->error->linkedJob = '删除失败,该Jenkins跟构建有关联,请取消关联或删除构建。';
+1
View File
@@ -20,6 +20,7 @@ $lang->jenkins->lblCreate = '添加Jenkins伺服器';
$lang->jenkins->desc = '描述';
$lang->jenkins->tokenFirst = 'Token不為空時,優先使用Token。';
$lang->jenkins->tips = '使用密碼時,請在Jenkins全局安全設置中禁用"防止跨站點請求偽造"選項。';
$lang->jenkins->serverList = '伺服器列表';
$lang->jenkins->error = new stdclass();
$lang->jenkins->error->linkedJob = '刪除失敗,該Jenkins跟構建有關聯,請取消關聯或刪除構建。';
+4 -1
View File
@@ -12,9 +12,13 @@
?>
<?php include '../../common/view/header.html.php'; ?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php echo html::a($this->createLink('jenkins', 'browse'), "<span class='text'>{$lang->jenkins->serverList}</span>", '', "class='btn btn-link btn-active-text'");?>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('jenkins', 'create')) common::printLink('jenkins', 'create', "", "<i class='icon icon-plus'></i> " . $lang->jenkins->create, '', "class='btn btn-primary'");?>
</div>
</div>
<?php if(empty($jenkinsList)):?>
<div class="table-empty-tip">
<p>
@@ -24,7 +28,6 @@
<?php endif;?>
</p>
</div>
</div>
<?php else:?>
<div id='mainContent' class='main-row'>
<form class='main-table' id='ajaxForm' method='post'>
+15 -18
View File
@@ -604,24 +604,30 @@ class kanban extends control
/**
* Delete a lane.
*
* @param int $regionID
* @param int $kanbanID
* @param int $laneID
* @param string $confirm no|yes
* @access public
* @return void
*/
public function deleteLane($laneID, $confirm = 'no')
public function deleteLane($regionID, $kanbanID, $laneID, $confirm = 'no')
{
if($confirm == 'no')
{
$laneType = $this->kanban->getLaneById($laneID)->type;
$confirmTip = in_array($laneType, array('story', 'task', 'bug')) ? sprintf($this->lang->kanbanlane->confirmDeleteTip, $this->lang->{$laneType}->common) : $this->lang->kanbanlane->confirmDelete;
return print(js::confirm($confirmTip, $this->createLink('kanban', 'deleteLane', "laneID=$laneID&confirm=yes"), ''));
return print(js::confirm($confirmTip, $this->createLink('kanban', 'deleteLane', "regionID=$regionID&kanbanID=$kanbanID&laneID=$laneID&confirm=yes"), ''));
}
else
{
$this->kanban->delete(TABLE_KANBANLANE, $laneID);
return print(js::reload('parent'));
$kanbanGroup = $this->kanban->getKanbanData($kanbanID, $regionID);
$kanbanGroup = json_encode($kanbanGroup);
return print("<script>parent.updateRegion($regionID, $kanbanGroup)</script>");
}
}
@@ -1487,7 +1493,9 @@ class kanban extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, $regionID)"));
}
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
$region = $this->kanban->getRegionByID($column->region);
$kanbanGroup = $this->kanban->getKanbanData($region->kanban, $region->id);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => array('target' => 'parent', 'name' => 'updateRegion', 'params' => array($column->region, $kanbanGroup))));
}
$this->app->loadLang('story');
@@ -1553,7 +1561,7 @@ class kanban extends control
$this->loadModel('action')->create('kanbanlane', $laneID, 'Edited', '', $executionID);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent', 'lane' => $lane));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => 1, 'callback' => array('target' => 'parent', 'name' => 'updateLaneName', 'params' => array($laneID, $this->post->name))));
}
$lane = $this->kanban->getLaneById($laneID);
@@ -1584,7 +1592,7 @@ class kanban extends control
$this->loadModel('action')->create('kanbanlane', $laneID, 'Edited', '', $executionID);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => array('target' => 'parent', 'name' => 'updateLaneColor', 'params' => array($laneID, $this->post->color))));
}
$lane = $this->kanban->getLaneById($laneID);
@@ -1619,19 +1627,8 @@ class kanban extends control
$this->action->logHistory($actionID, $changes);
}
if($from == 'RDKanban')
{
if(dao::isError()) return $this->sendError(dao::getError());
$execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all';
$execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default';
$regionID = $execGroupBy == 'default' ? $column->region : 0;
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $execLaneType, 'id_desc', $regionID, $execGroupBy);
$kanbanData = json_encode($kanbanData);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "parent.updateKanban($kanbanData, $regionID)"));
}
return $this->sendSuccess(array('locate' => 'parent'));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => array('target' => 'parent', 'name' => 'updateColumnName', 'params' => array($columnID, $this->post->name, $this->post->color))));
}
$this->view->canEdit = $from == 'RDKanban' ? 0 : 1;
+52 -2
View File
@@ -899,11 +899,59 @@ function updateRegion(regionID, regionData)
return true;
}
/**
* Update region name.
*
* @param int $regionID
* @param string $name
* @access public
* @return void
*/
function updateRegionName(regionID, name)
{
$('.region[data-id="' + regionID + '"] > .region-header > strong:first').text(name);
}
/**
* Update lane name.
*
* @param int $laneID
* @param string $name
* @access public
* @return void
*/
function updateLaneName(laneID, name)
{
$('.kanban-lane[data-id="' + laneID + '"] > .kanban-lane-name > span').text(name);
}
/**
* Update lane color.
*
* @param int $laneID
* @param string $color
* @access public
* @return void
*/
function updateLaneColor(laneID, color)
{
$('.kanban-lane[data-id="' + laneID + '"] > .kanban-lane-name').css('background-color', color);
}
/**
* Update column name.
*
* @param int $columnID
* @param string $name
* @param string $color
* @access public
* @return void
*/
function updateColumnName(columnID, name, color)
{
$('.kanban-col[data-id="' + columnID + '"] > div.title > span:first').text(name).css('color', color);
}
/**
* Hide kanban action
*/
@@ -1113,10 +1161,12 @@ function createLaneMenu(options)
var privs = lane.actions;
if(!privs.length) return [];
var items = [];
var items = [];
var regionID = lane.$kanbanData.region;
var kanbanID = lane.$kanbanData.kanban;
if(privs.includes('editLaneName')) items.push({label: kanbanLang.editLaneName, icon: 'edit', url: createLink('kanban', 'editLaneName', 'laneID=' + lane.id + '&executionID=0&from=kanban'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '635px'}});
if(privs.includes('editLaneColor')) items.push({label: kanbanLang.editLaneColor, icon: 'color', url: createLink('kanban', 'editLaneColor', 'laneID=' + lane.id + '&executionID=0&from=kanban'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '635px'}});
if(privs.includes('deleteLane')) items.push({label: kanbanLang.deleteLane, icon: 'trash', url: createLink('kanban', 'deleteLane', 'lane=' + lane.id), attrs: {'target': 'hiddenwin'}});
if(privs.includes('deleteLane')) items.push({label: kanbanLang.deleteLane, icon: 'trash', url: createLink('kanban', 'deleteLane', 'regionID=' + regionID + '&kanbanID=' + kanbanID + '&lane=' + lane.id), attrs: {'target': 'hiddenwin'}});
var bounds = options.$trigger[0].getBoundingClientRect();
items.$options = {x: bounds.right, y: bounds.top};
+3 -4
View File
@@ -1762,7 +1762,6 @@ class kanbanModel extends model
->where('deleted')->eq(0)
->andWhere('id')->in($spaceIdList)
->beginIF(in_array($browseType, array('private', 'cooperation', 'public')))->andWhere('type')->eq($browseType)->fi()
->beginIF($browseType == 'involved')->andWhere('owner')->ne($account)->fi()
->beginIF($this->cookie->showClosed == 0 and $browseType != 'showClosed')->andWhere('status')->ne('closed')->fi()
->orderBy('id_desc')
->fetchPairs('id');
@@ -1808,10 +1807,11 @@ class kanbanModel extends model
$account = $this->app->user->account;
foreach($objects as $objectID => $object)
{
$remove = true;
if($objectType == 'kanbanspace' and $object->type == 'public' and $param != 'involved') continue;
if($object->owner == $account and $param != 'involved') $remove = false;
$remove = true;
if($object->owner == $account) $remove = false;
if(strpos(",{$object->team},", ",$account,") !== false) $remove = false;
if(strpos(",{$object->whitelist},", ",$account,") !== false) $remove = false;
@@ -1823,7 +1823,6 @@ class kanbanModel extends model
if($spaceType == 'public' and $param != 'involved') $remove = false;
}
if($objectType == 'kanbanspace' and $param == 'involved' and $object->owner == $account) $remove = true;
if($remove) unset($objects[$objectID]);
}
+3
View File
@@ -18,3 +18,6 @@ td.delayed {background: #e84e0f !important; color: white;}
.c-status, .c-date, .c-user-short {width: 70px;}
.c-project {width: 130px;}
#taskTable .assigned-title{width: 110px; padding-left: 29px;}
html[lang="en"] .c-date {width: 80px;}
html[lang="en"] .c-user-short {width: 88px;}
+1 -2
View File
@@ -35,13 +35,12 @@
</div>
<div id="mainContent">
<?php $dataModule = $app->rawMethod == 'work' ? 'workBug' : 'contributeBug';?>
<?php if(empty($bugs)):?>
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $dataModule;?>></div>
<?php if(empty($bugs)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->bug->noBug;?></span></p>
</div>
<?php else:?>
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $dataModule;?>></div>
<form id='myBugForm' class="main-table table-bug" data-ride="table" method="post" action='<?php echo $this->createLink('bug', 'batchEdit', "productID=0");?>'>
<?php
$canBatchEdit = (common::hasPriv('bug', 'batchEdit') and $type == 'assignedTo');
+1 -1
View File
@@ -58,7 +58,7 @@
common::printIcon('testtask', 'cases', "taskID=$task->id", $task, 'list', 'sitemap', '', '', '', "data-app='qa'");
common::printIcon('testtask', 'view', "taskID=$task->id", '', 'list', 'list-alt', '', 'iframe', true, "data-width='90%'");
common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link', '', '', false, "data-app='qa'");
common::printIcon('testreport', 'browse', "objectID=$task->product&objectType=product&extra=$task->id", $task, 'list', 'flag', '', '', false, "data-app='qa'");
common::printIcon('testreport', 'browse', "objectID=$task->product&objectType=product&extra=$task->id", $task, 'list', 'summary', '', '', false, "data-app='qa'");
common::printIcon('testtask', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='90%'");
if(common::hasPriv('testtask', 'delete', $task))
{

Some files were not shown because too many files have changed in this diff Show More