Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms
This commit is contained in:
@@ -116,6 +116,17 @@ CREATE TABLE IF NOT EXISTS `zt_holiday` (
|
||||
KEY `name` (`name`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_mrapproval`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_mrapproval` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`mrID` mediumint(8) unsigned NOT NULL,
|
||||
`account` varchar(255) NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`action` char(30) NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
REPLACE INTO `zt_stage` (`name`,`percent`,`type`,`createdBy`,`createdDate`,`editedBy`,`editedDate`,`deleted`) VALUES
|
||||
('需求','10','request','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
|
||||
('设计','10','design','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
|
||||
|
||||
@@ -491,7 +491,7 @@ class baseHTML
|
||||
|
||||
$gobackLink = "<a href='javascript:history.go(-1)' class='btn btn-back $class' $misc>{$label}</a>";
|
||||
$tab = $_COOKIE['tab'];
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? strtolower($_SERVER['HTTP_REFERER']) : '';
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
|
||||
$refererParts = parse_url($referer);
|
||||
|
||||
if($config->requestType == 'PATH_INFO' and empty($refererParts)) return $gobackLink;
|
||||
@@ -504,7 +504,7 @@ class baseHTML
|
||||
$gobackLink = isset($gobackList[$tab]) ? $gobackList[$tab] : '';
|
||||
|
||||
/* If the link of the referer is not the link of the current page or the link of the index, the cookie and gobackLink will be updated. */
|
||||
if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", $refererLink))
|
||||
if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", strtolower($refererLink)))
|
||||
{
|
||||
$gobackList[$tab] = $referer;
|
||||
$gobackLink = $referer;
|
||||
|
||||
@@ -559,8 +559,11 @@ class gitlab
|
||||
$list = $this->fetch($api, $params);
|
||||
|
||||
$commits = array();
|
||||
$files = array();
|
||||
foreach($list as $commit)
|
||||
{
|
||||
if(!is_object($commit)) continue;
|
||||
|
||||
$log = new stdclass;
|
||||
$log->committer = $commit->committer_name;
|
||||
$log->revision = $commit->id;
|
||||
|
||||
@@ -535,6 +535,7 @@ $lang->action->label->stakeholder = 'Stakeholder|stakeholder|view|userID=%s';
|
||||
$lang->action->label->api = 'Interface|api|index|libID=%s&moduleID=%s&apiID=%s';
|
||||
$lang->action->label->kanbancolumn = 'Kanban column|execution|kanban|execution=%s';
|
||||
$lang->action->label->kanbanlane = 'Kanban Lane|execution|kanban|execution=%s&type=all';
|
||||
$lang->action->label->mr = 'Merge Request|mr|view|id=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search = new stdclass();
|
||||
|
||||
@@ -540,6 +540,7 @@ $lang->action->label->stakeholder = '干系人|stakeholder|view|userID=%s';
|
||||
$lang->action->label->api = '接口|api|index|libID=%s&moduleID=%s&apiID=%s';
|
||||
$lang->action->label->kanbancolumn = '看板列|execution|kanban|execution=%s';
|
||||
$lang->action->label->kanbanlane = '看板泳道|execution|kanban|execution=%s&type=all';
|
||||
$lang->action->label->mr = '合并请求|mr|view|id=%s';
|
||||
|
||||
/* Object type. */
|
||||
$lang->action->search = new stdclass();
|
||||
|
||||
@@ -103,48 +103,16 @@ $lang->block->spent = 'Has Been Spent';
|
||||
$lang->block->budget = 'Budget';
|
||||
$lang->block->left = 'Residuals';
|
||||
|
||||
$lang->block->default['waterfall']['project']['1']['title'] = 'Project Weekly';
|
||||
$lang->block->default['waterfall']['project']['1']['block'] = 'waterfallreport';
|
||||
$lang->block->default['waterfall']['project']['1']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['1']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['2']['title'] = 'Estimate';
|
||||
$lang->block->default['waterfall']['project']['2']['block'] = 'waterfallestimate';
|
||||
$lang->block->default['waterfall']['project']['2']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['2']['grid'] = 4;
|
||||
|
||||
$lang->block->default['waterfall']['project']['3']['title'] = 'Plan Gantt Chart';
|
||||
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
|
||||
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['4']['title'] = 'Progress Chart';
|
||||
$lang->block->default['waterfall']['project']['4']['block'] = 'waterfallprogress';
|
||||
$lang->block->default['waterfall']['project']['4']['grid'] = 4;
|
||||
|
||||
$lang->block->default['waterfall']['project']['5']['title'] = 'Project Issue';
|
||||
$lang->block->default['waterfall']['project']['5']['block'] = 'waterfallissue';
|
||||
$lang->block->default['waterfall']['project']['5']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['5']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['5']['params']['type'] = 'all';
|
||||
$lang->block->default['waterfall']['project']['5']['params']['count'] = '15';
|
||||
$lang->block->default['waterfall']['project']['5']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['waterfall']['project']['6']['title'] = 'Dynamic';
|
||||
$lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic';
|
||||
$lang->block->default['waterfall']['project']['6']['grid'] = 4;
|
||||
$lang->block->default['waterfall']['project']['6']['source'] = 'project';
|
||||
|
||||
$lang->block->default['waterfall']['project']['7']['title'] = 'Project Risk';
|
||||
$lang->block->default['waterfall']['project']['7']['block'] = 'waterfallrisk';
|
||||
$lang->block->default['waterfall']['project']['7']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['7']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['7']['params']['type'] = 'all';
|
||||
$lang->block->default['waterfall']['project']['7']['params']['count'] = '15';
|
||||
$lang->block->default['waterfall']['project']['7']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['scrum']['project']['1']['title'] = 'Project Overall';
|
||||
$lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview';
|
||||
$lang->block->default['scrum']['project']['1']['grid'] = 8;
|
||||
@@ -375,13 +343,8 @@ $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dyna
|
||||
|
||||
$lang->block->modules['waterfall']['index'] = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallreport = 'Project Weekly';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallestimate = 'Estimate';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallprogress = 'Progress Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue = 'Project Issue';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk = 'Project Risk';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
|
||||
$lang->block->modules['product'] = new stdclass();
|
||||
$lang->block->modules['product']->availableBlocks = new stdclass();
|
||||
|
||||
@@ -355,13 +355,8 @@ $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dyna
|
||||
|
||||
$lang->block->modules['waterfall']['index'] = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallreport = 'Project Weekly';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallestimate = 'Estimate';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallprogress = 'Progress Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue = 'Project Issue';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk = 'Project Risk';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
|
||||
$lang->block->modules['product'] = new stdclass();
|
||||
$lang->block->modules['product']->availableBlocks = new stdclass();
|
||||
|
||||
@@ -103,48 +103,16 @@ $lang->block->spent = 'Has Been Spent';
|
||||
$lang->block->budget = 'Budget';
|
||||
$lang->block->left = 'Residuals';
|
||||
|
||||
$lang->block->default['waterfall']['project']['1']['title'] = 'Project Weekly';
|
||||
$lang->block->default['waterfall']['project']['1']['block'] = 'waterfallreport';
|
||||
$lang->block->default['waterfall']['project']['1']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['1']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['2']['title'] = 'Estimate';
|
||||
$lang->block->default['waterfall']['project']['2']['block'] = 'waterfallestimate';
|
||||
$lang->block->default['waterfall']['project']['2']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['2']['grid'] = 4;
|
||||
|
||||
$lang->block->default['waterfall']['project']['3']['title'] = 'Plan Gantt Chart';
|
||||
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
|
||||
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['4']['title'] = 'Progress Chart';
|
||||
$lang->block->default['waterfall']['project']['4']['block'] = 'waterfallprogress';
|
||||
$lang->block->default['waterfall']['project']['4']['grid'] = 4;
|
||||
|
||||
$lang->block->default['waterfall']['project']['5']['title'] = 'project Issue';
|
||||
$lang->block->default['waterfall']['project']['5']['block'] = 'waterfallissue';
|
||||
$lang->block->default['waterfall']['project']['5']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['5']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['5']['params']['type'] = 'all';
|
||||
$lang->block->default['waterfall']['project']['5']['params']['count'] = '15';
|
||||
$lang->block->default['waterfall']['project']['5']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['waterfall']['project']['6']['title'] = 'Dynamic';
|
||||
$lang->block->default['waterfall']['project']['6']['block'] = 'dynamic';
|
||||
$lang->block->default['waterfall']['project']['6']['grid'] = 4;
|
||||
$lang->block->default['waterfall']['project']['6']['source'] = '';
|
||||
|
||||
$lang->block->default['waterfall']['project']['7']['title'] = 'Project Risk';
|
||||
$lang->block->default['waterfall']['project']['7']['block'] = 'waterfallrisk';
|
||||
$lang->block->default['waterfall']['project']['7']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['7']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['7']['params']['type'] = 'all';
|
||||
$lang->block->default['waterfall']['project']['7']['params']['count'] = '15';
|
||||
$lang->block->default['waterfall']['project']['7']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['scrum']['project']['1']['title'] = 'Project Overall';
|
||||
$lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview';
|
||||
$lang->block->default['scrum']['project']['1']['grid'] = 8;
|
||||
@@ -375,13 +343,8 @@ $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dyna
|
||||
|
||||
$lang->block->modules['waterfall']['index'] = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallreport = 'Project Weekly';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallestimate = 'Estimate';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallprogress = 'Progress Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue = 'Project Issue';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk = 'Project Risk';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
|
||||
$lang->block->modules['product'] = new stdclass();
|
||||
$lang->block->modules['product']->availableBlocks = new stdclass();
|
||||
|
||||
@@ -103,48 +103,16 @@ $lang->block->spent = 'Has Been Spent';
|
||||
$lang->block->budget = 'Budget';
|
||||
$lang->block->left = 'Residuals';
|
||||
|
||||
$lang->block->default['waterfall']['project']['1']['title'] = 'Project Weekly';
|
||||
$lang->block->default['waterfall']['project']['1']['block'] = 'waterfallreport';
|
||||
$lang->block->default['waterfall']['project']['1']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['1']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['2']['title'] = 'Estimate';
|
||||
$lang->block->default['waterfall']['project']['2']['block'] = 'waterfallestimate';
|
||||
$lang->block->default['waterfall']['project']['2']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['2']['grid'] = 4;
|
||||
|
||||
$lang->block->default['waterfall']['project']['3']['title'] = 'Plan Gantt Chart';
|
||||
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
|
||||
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['4']['title'] = 'Progress Chart';
|
||||
$lang->block->default['waterfall']['project']['4']['block'] = 'waterfallprogress';
|
||||
$lang->block->default['waterfall']['project']['4']['grid'] = 4;
|
||||
|
||||
$lang->block->default['waterfall']['project']['5']['title'] = 'Project Issue';
|
||||
$lang->block->default['waterfall']['project']['5']['block'] = 'waterfallissue';
|
||||
$lang->block->default['waterfall']['project']['5']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['5']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['5']['params']['type'] = 'all';
|
||||
$lang->block->default['waterfall']['project']['5']['params']['count'] = '15';
|
||||
$lang->block->default['waterfall']['project']['5']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['waterfall']['project']['6']['title'] = 'Dynamic';
|
||||
$lang->block->default['waterfall']['project']['6']['block'] = 'dynamic';
|
||||
$lang->block->default['waterfall']['project']['6']['grid'] = 4;
|
||||
$lang->block->default['waterfall']['project']['6']['source'] = 'project';
|
||||
|
||||
$lang->block->default['waterfall']['project']['7']['title'] = 'Project Risk';
|
||||
$lang->block->default['waterfall']['project']['7']['block'] = 'waterfallrisk';
|
||||
$lang->block->default['waterfall']['project']['7']['source'] = 'project';
|
||||
$lang->block->default['waterfall']['project']['7']['grid'] = 8;
|
||||
|
||||
$lang->block->default['waterfall']['project']['7']['params']['type'] = 'all';
|
||||
$lang->block->default['waterfall']['project']['7']['params']['count'] = '15';
|
||||
$lang->block->default['waterfall']['project']['7']['params']['orderBy'] = 'id_desc';
|
||||
|
||||
$lang->block->default['scrum']['project']['1']['title'] = 'Project Overall';
|
||||
$lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview';
|
||||
$lang->block->default['scrum']['project']['1']['grid'] = 8;
|
||||
@@ -375,13 +343,8 @@ $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dyna
|
||||
|
||||
$lang->block->modules['waterfall']['index'] = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallreport = $lang->executionCommon . ' Weekly';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallestimate = 'Estimate';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallprogress = 'Progress Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue = $lang->executionCommon . ' Issue';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk = $lang->executionCommon . ' Risk';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics';
|
||||
|
||||
$lang->block->modules['product'] = new stdclass();
|
||||
$lang->block->modules['product']->availableBlocks = new stdclass();
|
||||
|
||||
@@ -355,12 +355,7 @@ $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = '最
|
||||
|
||||
$lang->block->modules['waterfall']['index'] = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks = new stdclass();
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallreport = '项目周报';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallestimate = '估算';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = "项目计划";
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallprogress = '到目前为止项目进展趋势图';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue = '项目问题';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk = '项目风险';
|
||||
$lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = '最新动态';
|
||||
|
||||
$lang->block->modules['product'] = new stdclass();
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php $waterfallGanttID = uniqid('wg'); ?>
|
||||
|
||||
<div class="panel-body">
|
||||
<div id='waterfallGantt'>
|
||||
<div id='<?php echo $waterfallGanttID; ?>'>
|
||||
<?php if(count($products) >= 2): ?>
|
||||
<?php echo html::select('waterfallGanttProductID', $products, $productID, "class='form-control chosen'");?>
|
||||
<span id="ganttProductTips"><i>* </i><?php echo $lang->block->selectProduct;?></span>
|
||||
<?php echo html::select($waterfallGanttID . 'ProductID', $products, $productID, "class='form-control chosen'");?>
|
||||
<span class='gantt-product-tips'><i>* </i><?php echo $lang->block->selectProduct;?></span>
|
||||
<?php endif;?>
|
||||
<?php if(empty($plans['data'])): ?>
|
||||
<div class='empty-tip'><?php echo $lang->programplan->noData;?></div>
|
||||
@@ -18,12 +20,12 @@
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<style>
|
||||
#ganttProductTips{position: absolute; top: -32px; left: 240px; opacity: 0.5;}
|
||||
#ganttProductTips i{vertical-align: middle;}
|
||||
.gantt-product-tips {position: absolute; top: -32px; left: 240px; opacity: 0.5;}
|
||||
.gantt-product-tips i {vertical-align: middle;}
|
||||
.block-waterfallgantt > .panel-body {overflow: visible!important}
|
||||
#waterfallGantt {position: relative}
|
||||
#waterfallGanttProductID_chosen {position: absolute; top: -39px; left: 120px; width: 150px!important}
|
||||
[lang="zh-cn"] #waterfallGanttProductID_chosen {left: 85px}
|
||||
#<?php echo $waterfallGanttID; ?> {position: relative}
|
||||
#<?php echo $waterfallGanttID; ?>ProductID_chosen {position: absolute; top: -39px; left: 120px; width: 150px!important}
|
||||
[lang="zh-cn"] #<?php echo $waterfallGanttID; ?>ProductID_chosen {left: 85px}
|
||||
.gantt-plans {padding: 20px 0 22px; max-height: 380px; overflow: hidden;}
|
||||
.gantt-plan {width: 70px; height: 50px; line-height: 50px}
|
||||
.gantt-plan div {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
|
||||
@@ -39,171 +41,173 @@
|
||||
.gantt-today {position: absolute; top: -16px; left: 0; bottom: 0; border-left: #00da88 dotted 1px;}
|
||||
.gantt-today > div {position: absolute; top: 0; left: 0; font-size: 12px; line-height: 14px; padding: 0 3px; background: #00da88; color: #fff; white-space: nowrap; z-index: 10;}
|
||||
</style>
|
||||
<script>
|
||||
function initWaterfallGanttBlock()
|
||||
{
|
||||
/* Init product select control */
|
||||
var $waterfallGanttProductID = $('#waterfallGanttProductID');
|
||||
$waterfallGanttProductID.on('change', function()
|
||||
{
|
||||
$.get(createLink('product', 'ajaxSetState', 'productID=' + $waterfallGanttProductID.val()), function()
|
||||
{
|
||||
refreshBlock($waterfallGanttProductID.closest('.panel'));
|
||||
});
|
||||
});
|
||||
<script>
|
||||
(function() {
|
||||
function initWaterfallGanttBlock()
|
||||
{
|
||||
/* Init product select control */
|
||||
var $waterfallGanttProductID = $('#<?php echo $waterfallGanttID; ?>ProductID');
|
||||
$waterfallGanttProductID.on('change', function()
|
||||
{
|
||||
$.get(createLink('product', 'ajaxSetState', 'productID=' + $waterfallGanttProductID.val()), function()
|
||||
{
|
||||
refreshBlock($waterfallGanttProductID.closest('.panel'));
|
||||
});
|
||||
});
|
||||
|
||||
<?php if(!empty($plans['data'])): ?>
|
||||
var ganttData = <?php echo json_encode($plans['data']); ?>;
|
||||
if(!ganttData) return;
|
||||
<?php if(!empty($plans['data'])): ?>
|
||||
var ganttData = <?php echo json_encode($plans['data']); ?>;
|
||||
if(!ganttData) return;
|
||||
|
||||
var plans = [];
|
||||
var tasks = [];
|
||||
var plansMap = {};
|
||||
var startDatetime = Number.MAX_SAFE_INTEGER;
|
||||
var endDatetime = 0;
|
||||
var minTimeGap = Number.MAX_SAFE_INTEGER;
|
||||
var $gantt = $('#waterfallGantt');
|
||||
var ONE_DAY = 24 * 3600 * 1000;
|
||||
var TIME_GAP_STEP = 7;
|
||||
var MIN_COL_WIDTH = 60;
|
||||
var plans = [];
|
||||
var tasks = [];
|
||||
var plansMap = {};
|
||||
var startDatetime = Number.MAX_SAFE_INTEGER;
|
||||
var endDatetime = 0;
|
||||
var minTimeGap = Number.MAX_SAFE_INTEGER;
|
||||
var $gantt = $('#<?php echo $waterfallGanttID; ?>');
|
||||
var ONE_DAY = 24 * 3600 * 1000;
|
||||
var TIME_GAP_STEP = 7;
|
||||
var MIN_COL_WIDTH = 60;
|
||||
|
||||
$.each(ganttData, function(index, item)
|
||||
{
|
||||
plansMap[item.id] = item;
|
||||
if(item.type == 'plan' && item.parent == '0')
|
||||
{
|
||||
item.startDatetime = createDatetime(item.start_date);
|
||||
item.endDatetime = createDatetime(item.deadline);
|
||||
startDatetime = Math.min(startDatetime, item.startDatetime);
|
||||
endDatetime = Math.max(endDatetime, item.endDatetime);
|
||||
minTimeGap = Math.min(minTimeGap, endDatetime - startDatetime);
|
||||
item.tasks = [];
|
||||
item.completeTasks = [];
|
||||
item.progress = 0;
|
||||
plans.push(item);
|
||||
}
|
||||
else if(item.type === 'task')
|
||||
{
|
||||
item.progress = Number.parseInt(item.taskProgress.replace('%', ''), 10);
|
||||
tasks.push(item);
|
||||
}
|
||||
});
|
||||
$.each(ganttData, function(index, item)
|
||||
{
|
||||
plansMap[item.id] = item;
|
||||
if(item.type == 'plan' && item.parent == '0')
|
||||
{
|
||||
item.startDatetime = createDatetime(item.start_date);
|
||||
item.endDatetime = createDatetime(item.deadline);
|
||||
startDatetime = Math.min(startDatetime, item.startDatetime);
|
||||
endDatetime = Math.max(endDatetime, item.endDatetime);
|
||||
minTimeGap = Math.min(minTimeGap, endDatetime - startDatetime);
|
||||
item.tasks = [];
|
||||
item.completeTasks = [];
|
||||
item.progress = 0;
|
||||
plans.push(item);
|
||||
}
|
||||
else if(item.type === 'task')
|
||||
{
|
||||
item.progress = Number.parseInt(item.taskProgress.replace('%', ''), 10);
|
||||
tasks.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
$.each(tasks, function(index, task)
|
||||
{
|
||||
var plan = plansMap[task.parent];
|
||||
while(plan.parent > 0)
|
||||
{
|
||||
plan = plansMap[plan.parent];
|
||||
if(typeof(plan) != 'object') return;
|
||||
}
|
||||
plan.progress += task.progress;
|
||||
if(task.progress === 100) plan.completeTasks.push(task);
|
||||
plan.tasks.push(task);
|
||||
});
|
||||
$.each(tasks, function(index, task)
|
||||
{
|
||||
var plan = plansMap[task.parent];
|
||||
while(plan.parent > 0)
|
||||
{
|
||||
plan = plansMap[plan.parent];
|
||||
if(typeof(plan) != 'object') return;
|
||||
}
|
||||
plan.progress += task.progress;
|
||||
if(task.progress === 100) plan.completeTasks.push(task);
|
||||
plan.tasks.push(task);
|
||||
});
|
||||
|
||||
var $plans = $gantt.find('.gantt-plans');
|
||||
var $ganttContainer = $gantt.find('.gantt-container');
|
||||
var $ganttCanvas = $gantt.find('.gantt-canvas');
|
||||
var themeColor = $.getThemeColor('primary');
|
||||
var canvasHeight = plans.length * 50 + 10;
|
||||
var $plans = $gantt.find('.gantt-plans');
|
||||
var $ganttContainer = $gantt.find('.gantt-container');
|
||||
var $ganttCanvas = $gantt.find('.gantt-canvas');
|
||||
var themeColor = $.getThemeColor('primary');
|
||||
var canvasHeight = plans.length * 50 + 10;
|
||||
|
||||
var days = Math.ceil((endDatetime - startDatetime) / ONE_DAY);
|
||||
minTimeGap = Math.max(1, Math.ceil(minTimeGap / ONE_DAY));
|
||||
var days = Math.ceil((endDatetime - startDatetime) / ONE_DAY);
|
||||
minTimeGap = Math.max(1, Math.ceil(minTimeGap / ONE_DAY));
|
||||
|
||||
/* Update gantt plans and bars */
|
||||
$.each(plans, function(index, plan)
|
||||
{
|
||||
plan.progress = !plan.tasks.length ? 0 : plan.progress / plan.tasks.length;
|
||||
var $plan = $('<div class="gantt-plan"></div>');
|
||||
$plan.append('<div class="strong" title="' + plan.text + '">' + plan.text + '</div>');
|
||||
$plans.append($plan);
|
||||
/* Update gantt plans and bars */
|
||||
$.each(plans, function(index, plan)
|
||||
{
|
||||
plan.progress = !plan.tasks.length ? 0 : plan.progress / plan.tasks.length;
|
||||
var $plan = $('<div class="gantt-plan"></div>');
|
||||
$plan.append('<div class="strong" title="' + plan.text + '">' + plan.text + '</div>');
|
||||
$plans.append($plan);
|
||||
|
||||
var $bar = $('<div class="gantt-bar"></div>');
|
||||
$('<div class="gantt-bar-progress bg-primary"></div>').css(
|
||||
{
|
||||
width: plan.progress + '%',
|
||||
background: themeColor,
|
||||
}).appendTo($bar);
|
||||
$bar.append('<div class="gantt-task-info text-muted small"><?php echo $lang->programplan->task;?> ' + plan.completeTasks.length + '/' + plan.tasks.length + '</div>').attr('title', $.zui.formatDate(plan.startDatetime, 'yyyy-MM-dd') + '~' + $.zui.formatDate(plan.endDatetime, 'yyyy-MM-dd'));
|
||||
var $row = $('<div class="gantt-row" data-id="' + plan.id + '"></div>').append($bar);
|
||||
$ganttCanvas.append($row);
|
||||
});
|
||||
var $bar = $('<div class="gantt-bar"></div>');
|
||||
$('<div class="gantt-bar-progress bg-primary"></div>').css(
|
||||
{
|
||||
width: plan.progress + '%',
|
||||
background: themeColor,
|
||||
}).appendTo($bar);
|
||||
$bar.append('<div class="gantt-task-info text-muted small"><?php echo $lang->programplan->task;?> ' + plan.completeTasks.length + '/' + plan.tasks.length + '</div>').attr('title', $.zui.formatDate(plan.startDatetime, 'yyyy-MM-dd') + '~' + $.zui.formatDate(plan.endDatetime, 'yyyy-MM-dd'));
|
||||
var $row = $('<div class="gantt-row" data-id="' + plan.id + '"></div>').append($bar);
|
||||
$ganttCanvas.append($row);
|
||||
});
|
||||
|
||||
/* Layout gantt container */
|
||||
$ganttContainer.css('left', $plans.width() + 15);
|
||||
$ganttCanvas.css('height', canvasHeight);
|
||||
/* Layout gantt container */
|
||||
$ganttContainer.css('left', $plans.width() + 15);
|
||||
$ganttCanvas.css('height', canvasHeight);
|
||||
|
||||
/* Layout gantt */
|
||||
layoutGantt();
|
||||
$(window).on('resize', layoutGantt);
|
||||
setTimeout(layoutGantt, 100);
|
||||
/* Layout gantt */
|
||||
layoutGantt();
|
||||
$(window).on('resize', layoutGantt);
|
||||
setTimeout(layoutGantt, 100);
|
||||
|
||||
/* Bind events */
|
||||
$ganttContainer.on('scroll', function()
|
||||
{
|
||||
$plans.scrollTop($ganttContainer.scrollTop());
|
||||
});
|
||||
/* Bind events */
|
||||
$ganttContainer.on('scroll', function()
|
||||
{
|
||||
$plans.scrollTop($ganttContainer.scrollTop());
|
||||
});
|
||||
|
||||
/**
|
||||
* Layout gantt
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function layoutGantt()
|
||||
{
|
||||
var minWidth = $ganttContainer.width();
|
||||
var timeGap = minTimeGap < TIME_GAP_STEP ? minTimeGap : Math.floor(minTimeGap / TIME_GAP_STEP) * TIME_GAP_STEP;
|
||||
var colsCount = Math.ceil(days / timeGap);
|
||||
var canvasWidth = Math.max(minWidth, colsCount * MIN_COL_WIDTH);
|
||||
var colWidth = Math.floor(canvasWidth / colsCount);
|
||||
var pxPerMs = colWidth / (timeGap * ONE_DAY);
|
||||
$ganttCanvas.css('width', canvasWidth).find('.gantt-col').remove();
|
||||
for (var i = 0; i < colsCount; ++i)
|
||||
{
|
||||
var $col = $('<div class="gantt-col"></div>');
|
||||
$col.css(
|
||||
{
|
||||
left: i * colWidth,
|
||||
width: colWidth,
|
||||
height: canvasHeight
|
||||
});
|
||||
var colTime = startDatetime + i * timeGap * ONE_DAY;
|
||||
$col.append('<div class="gantt-col-time text-muted small">' + $.zui.formatDate(colTime, 'MM/dd') + '</div>');
|
||||
$ganttCanvas.append($col);
|
||||
}
|
||||
/**
|
||||
* Layout gantt
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function layoutGantt()
|
||||
{
|
||||
var minWidth = $ganttContainer.width();
|
||||
var timeGap = minTimeGap < TIME_GAP_STEP ? minTimeGap : Math.floor(minTimeGap / TIME_GAP_STEP) * TIME_GAP_STEP;
|
||||
var colsCount = Math.ceil(days / timeGap);
|
||||
var canvasWidth = Math.max(minWidth, colsCount * MIN_COL_WIDTH);
|
||||
var colWidth = Math.floor(canvasWidth / colsCount);
|
||||
var pxPerMs = colWidth / (timeGap * ONE_DAY);
|
||||
$ganttCanvas.css('width', canvasWidth).find('.gantt-col').remove();
|
||||
for (var i = 0; i < colsCount; ++i)
|
||||
{
|
||||
var $col = $('<div class="gantt-col"></div>');
|
||||
$col.css(
|
||||
{
|
||||
left: i * colWidth,
|
||||
width: colWidth,
|
||||
height: canvasHeight
|
||||
});
|
||||
var colTime = startDatetime + i * timeGap * ONE_DAY;
|
||||
$col.append('<div class="gantt-col-time text-muted small">' + $.zui.formatDate(colTime, 'MM/dd') + '</div>');
|
||||
$ganttCanvas.append($col);
|
||||
}
|
||||
|
||||
$.each(plans, function(index, plan)
|
||||
{
|
||||
var $planRow = $gantt.find('.gantt-row[data-id="' + plan.id + '"]');
|
||||
$planRow.find('.gantt-bar').css(
|
||||
{
|
||||
left: Math.floor((plan.startDatetime - startDatetime) * pxPerMs),
|
||||
width: Math.floor((plan.endDatetime - plan.startDatetime) * pxPerMs)
|
||||
});
|
||||
});
|
||||
$.each(plans, function(index, plan)
|
||||
{
|
||||
var $planRow = $gantt.find('.gantt-row[data-id="' + plan.id + '"]');
|
||||
$planRow.find('.gantt-bar').css(
|
||||
{
|
||||
left: Math.floor((plan.startDatetime - startDatetime) * pxPerMs),
|
||||
width: Math.floor((plan.endDatetime - plan.startDatetime) * pxPerMs)
|
||||
});
|
||||
});
|
||||
|
||||
$gantt.find('.gantt-today').css('left', (Date.now() - startDatetime) * pxPerMs);
|
||||
}
|
||||
$gantt.find('.gantt-today').css('left', (Date.now() - startDatetime) * pxPerMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create date from string
|
||||
*
|
||||
* @param {String} dateStr like '2020-08-02'
|
||||
* @return {Number} Date timestramp
|
||||
*/
|
||||
function createDatetime(dateStr)
|
||||
{
|
||||
dateStr = dateStr.split('-');
|
||||
var year = Number.parseInt(dateStr[0].length > 3 ? dateStr[0] : dateStr[2], 10);
|
||||
var month = Number.parseInt(dateStr[1], 10);
|
||||
var day = Number.parseInt(dateStr[2].length > 3 ? dateStr[0] : dateStr[2], 10);
|
||||
return new Date(year, month - 1, day).getTime();
|
||||
}
|
||||
/**
|
||||
* Create date from string
|
||||
*
|
||||
* @param {String} dateStr like '2020-08-02'
|
||||
* @return {Number} Date timestramp
|
||||
*/
|
||||
function createDatetime(dateStr)
|
||||
{
|
||||
dateStr = dateStr.split('-');
|
||||
var year = Number.parseInt(dateStr[0].length > 3 ? dateStr[0] : dateStr[2], 10);
|
||||
var month = Number.parseInt(dateStr[1], 10);
|
||||
var day = Number.parseInt(dateStr[2].length > 3 ? dateStr[0] : dateStr[2], 10);
|
||||
return new Date(year, month - 1, day).getTime();
|
||||
}
|
||||
|
||||
<?php endif;?>
|
||||
}
|
||||
<?php endif;?>
|
||||
}
|
||||
|
||||
initWaterfallGanttBlock();
|
||||
</script>
|
||||
initWaterfallGanttBlock();
|
||||
}());
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -883,6 +883,7 @@ class bug extends control
|
||||
$bug = $this->bug->getById($bugID);
|
||||
$productID = $bug->product;
|
||||
$executionID = $bug->execution;
|
||||
$projectID = $bug->project;
|
||||
$currentModuleID = $bug->module;
|
||||
$this->bug->checkBugExecutionPriv($bug);
|
||||
|
||||
@@ -928,6 +929,10 @@ class bug extends control
|
||||
{
|
||||
$openedBuilds = $this->build->getExecutionBuildPairs($executionID, $productID, $bug->branch, 'noempty,noterminate,nodone');
|
||||
}
|
||||
elseif($projectID)
|
||||
{
|
||||
$openedBuilds = $this->build->getProjectBuildPairs($projectID, $productID, $bug->branch, 'noempty,noterminate,nodone');
|
||||
}
|
||||
else
|
||||
{
|
||||
$openedBuilds = $this->build->getProductBuildPairs($productID, $bug->branch, 'noempty,noterminate,nodone');
|
||||
|
||||
@@ -278,6 +278,7 @@ function loadProductExecutions(productID, projectID = 0)
|
||||
if(typeof(bugExecution) == 'string' && systemMode != 'classic') $('#executionIdBox').prepend("<span class='input-group-addon' style='border-left-width: 0px;'>" + bugExecution + "</span>");
|
||||
if(required) $(this).addClass('required');
|
||||
});
|
||||
loadProjectBuilds(projectID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,6 +394,44 @@ function loadExecutionStories(executionID)
|
||||
$('#storyIdBox').load(link, function(){$('#story').chosen();});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load builds of a project.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function loadProjectBuilds(projectID)
|
||||
{
|
||||
var branch = $('#branch').val();
|
||||
if(typeof(branch) == 'undefined') branch = 0;
|
||||
var productID = $('#product').val();
|
||||
var oldOpenedBuild = $('#openedBuild').val() ? $('#openedBuild').val() : 0;
|
||||
|
||||
if(page == 'create')
|
||||
{
|
||||
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + "&branch=" + branch);
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="openedBuild" name="openedBuild" class="form-control" multiple=multiple></select>';
|
||||
$('#openedBuild').replaceWith(data);
|
||||
$('#openedBuild').val(oldOpenedBuild);
|
||||
$('#openedBuild_chosen').remove();
|
||||
$('#openedBuild').next('.picker').remove();
|
||||
$("#openedBuild").chosen();
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch);
|
||||
$('#openedBuildBox').load(link, function(){$(this).find('select').val(oldOpenedBuild).chosen()});
|
||||
|
||||
var oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
|
||||
var link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
|
||||
$('#resolvedBuildBox').load(link, function(){$(this).find('select').val(oldResolvedBuild).chosen()});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load builds of a execution.
|
||||
*
|
||||
|
||||
@@ -380,6 +380,42 @@ class build extends control
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: get builds of a project in html select.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $varName the name of the select object to create
|
||||
* @param string $build build to selected
|
||||
* @param string|int $branch
|
||||
* @param int $index the index of batch create bug.
|
||||
* @param bool $needCreate if need to append the link of create build
|
||||
* @param string $type get all builds or some builds belong to normal releases and executions are not done.
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function ajaxGetProjectBuilds($projectID, $productID, $varName, $build = '', $branch = 'all', $index = 0, $needCreate = false, $type = 'normal')
|
||||
{
|
||||
$isJsonView = $this->app->getViewType() == 'json';
|
||||
if($varName == 'openedBuild')
|
||||
{
|
||||
if(empty($projectID)) $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$params = ($type == 'all') ? 'noempty' : 'noempty, noterminate, nodone';
|
||||
$builds = $this->build->getProjectBuildPairs($projectID, $productID, $branch, $params, $build);
|
||||
if($isJsonView) die(json_encode($builds));
|
||||
die(html::select($varName . '[]', $builds , '', 'size=4 class=form-control multiple'));
|
||||
}
|
||||
if($varName == 'resolvedBuild')
|
||||
{
|
||||
if(empty($projectID)) $this->ajaxGetProductBuilds($productID, $varName, $build, $branch, $index, $type);
|
||||
|
||||
$params = ($type == 'all') ? '' : 'noterminate, nodone';
|
||||
$builds = $this->build->getProjectBuildPairs($projectID, $productID, $branch, $params, $build);
|
||||
if($isJsonView) die(json_encode($builds));
|
||||
die(html::select($varName, $builds, $build, "class='form-control'"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: get builds of an execution in html select.
|
||||
*
|
||||
|
||||
@@ -1402,13 +1402,6 @@ class execution extends control
|
||||
}
|
||||
}
|
||||
|
||||
$isStage = false;
|
||||
if(!empty($project->model) and $project->model == 'waterfall')
|
||||
{
|
||||
$isStage = true;
|
||||
$this->lang->execution->type = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->execution->type);
|
||||
}
|
||||
|
||||
$this->loadModel('user');
|
||||
$poUsers = $this->user->getPairs('noclosed|nodeleted|pofirst', '', $this->config->maxCount);
|
||||
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["PM"] = $this->config->user->moreLink;
|
||||
|
||||
@@ -921,7 +921,7 @@ $(function()
|
||||
{
|
||||
$.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy), function(data)
|
||||
{
|
||||
if(data && lastUpdateData !== lastUpdateData)
|
||||
if(data && lastUpdateData !== data)
|
||||
{
|
||||
lastUpdateData = data;
|
||||
kanbanGroup = $.parseJSON(data);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<?php js::set('errorSameProducts', $lang->execution->errorSameProducts);?>
|
||||
<?php js::set('errorSameBranches', $lang->execution->errorSameBranches);?>
|
||||
<?php js::set('productID', empty($productID) ? 0 : $productID);?>
|
||||
<?php js::set('isStage', false);?>
|
||||
<?php js::set('isStage', $isStage);?>
|
||||
<?php js::set('copyExecutionID', $copyExecutionID);?>
|
||||
<?php js::set('systemMode', $config->systemMode);?>
|
||||
<?php js::set('projectCommon', $lang->project->common);?>
|
||||
|
||||
@@ -967,6 +967,7 @@ class gitlab extends control
|
||||
$repo = $this->loadModel('repo')->getRepoByID($repoID);
|
||||
$users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
|
||||
$projectMembers = $this->gitlab->apiGetProjectMembers($repo->gitlab, $repo->project);
|
||||
if(!is_array($projectMembers)) $projectMembers = array();
|
||||
|
||||
/* Get users accesslevel. */
|
||||
$userAccessData = array();
|
||||
@@ -975,6 +976,7 @@ class gitlab extends control
|
||||
->where('providerType')->eq('gitlab')
|
||||
->andWhere('providerID')->eq($repo->gitlab)
|
||||
->fetchPairs();
|
||||
|
||||
foreach($projectMembers as $projectMember)
|
||||
{
|
||||
if(isset($projectMember->id) and isset($bindedUsers[$projectMember->id]))
|
||||
|
||||
+16
-10
@@ -7,7 +7,7 @@ $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->webhook = 'Webhook';
|
||||
$lang->gitlab->bindProduct = 'Import Product';
|
||||
$lang->gitlab->importIssue = 'Import Issue';
|
||||
$lang->gitlab->delete = 'Delete GitLab';
|
||||
@@ -33,9 +33,9 @@ $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->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';
|
||||
@@ -78,14 +78,20 @@ $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->errorLang[0] = 'You cannot set Internal as its Visibility Level, if it is private in Gitlab.';
|
||||
$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->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->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";
|
||||
@@ -102,7 +108,7 @@ $lang->gitlab->project->tagListTips = "Separate topics with comma
|
||||
$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->notbindedError = 'GitLab user has not been bound, unable to modify permissions!';
|
||||
|
||||
$lang->gitlab->user = new stdclass;
|
||||
$lang->gitlab->user->id = "User ID";
|
||||
@@ -124,8 +130,8 @@ $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->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!";
|
||||
|
||||
@@ -7,7 +7,7 @@ $lang->gitlab->create = '添加GitLab';
|
||||
$lang->gitlab->edit = '编辑GitLab';
|
||||
$lang->gitlab->view = '查看GitLab';
|
||||
$lang->gitlab->bindUser = '绑定用户';
|
||||
$lang->gitlab->webhook = 'webhook';
|
||||
$lang->gitlab->webhook = 'Webhook';
|
||||
$lang->gitlab->bindProduct = '关联产品';
|
||||
$lang->gitlab->importIssue = '关联issue';
|
||||
$lang->gitlab->delete = '删除GitLab';
|
||||
@@ -19,7 +19,7 @@ $lang->gitlab->binded = '已绑定';
|
||||
$lang->gitlab->serverFail = '连接GitLab服务器异常,请检查GitLab服务器。';
|
||||
$lang->gitlab->lastUpdate = '最后更新';
|
||||
$lang->gitlab->confirmAddWebhook = '您确定创建Webhook吗?';
|
||||
$lang->gitlab->addWebhookSuccess = 'webhook创建成功';
|
||||
$lang->gitlab->addWebhookSuccess = 'Webhook创建成功';
|
||||
$lang->gitlab->failCreateWebhook = 'Webhook创建失败,请查看日志';
|
||||
$lang->gitlab->placeholderSearch = '请输入项目名称';
|
||||
|
||||
@@ -33,9 +33,9 @@ $lang->gitlab->gitlabIssue = "{$lang->gitlab->common} issue";
|
||||
$lang->gitlab->zentaoProduct = '禅道产品';
|
||||
$lang->gitlab->objectType = '类型'; // task, bug, story
|
||||
$lang->gitlab->manageProjectMembers = '项目成员管理';
|
||||
$lang->gitlab->createProject = '添加Gitlab项目';
|
||||
$lang->gitlab->editProject = '编辑Gitlab项目';
|
||||
$lang->gitlab->deleteProject = '删除Gitlab项目';
|
||||
$lang->gitlab->createProject = '添加GitLab项目';
|
||||
$lang->gitlab->editProject = '编辑GitLab项目';
|
||||
$lang->gitlab->deleteProject = '删除GitLab项目';
|
||||
$lang->gitlab->createGroup = '添加群组';
|
||||
$lang->gitlab->editGroup = '编辑群组';
|
||||
$lang->gitlab->deleteGroup = '删除群组';
|
||||
@@ -59,7 +59,7 @@ $lang->gitlab->tips = '使用密码时,请在GitLab全局安全设置中
|
||||
|
||||
$lang->gitlab->placeholder = new stdclass;
|
||||
$lang->gitlab->placeholder->name = '';
|
||||
$lang->gitlab->placeholder->url = "请填写Gitlab Server首页的访问地址,如:https://gitlab.zentao.net。";
|
||||
$lang->gitlab->placeholder->url = "请填写GitLab Server首页的访问地址,如:https://gitlab.zentao.net。";
|
||||
$lang->gitlab->placeholder->token = "请填写具有admin权限账户的access token";
|
||||
$lang->gitlab->placeholder->projectPath = "项目标识串只能包含字母、数字、“_”、“-”和“.”。不能以“-”开头,以.git或者.atom结尾";
|
||||
|
||||
@@ -79,15 +79,19 @@ $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->errorLang[0] = '私有分组的项目,可见性级别不能设为内部。';
|
||||
$lang->gitlab->errorLang[1] = '私有分组的项目,可见性级别不能设为公开。';
|
||||
$lang->gitlab->errorLang[2] = '密码太短(最少8个字符)';
|
||||
$lang->gitlab->errorLang[3] = "只能包含字母、数字、'.'-'和'.'。不能以'-'开头、以'.git'结尾或以'.atom'结尾。";
|
||||
|
||||
$lang->gitlab->project = new stdclass;
|
||||
$lang->gitlab->project->id = "项目ID";
|
||||
$lang->gitlab->project->name = "项目名称";
|
||||
$lang->gitlab->project->create = "添加Gitlab项目";
|
||||
$lang->gitlab->project->edit = "编辑Gitlab项目";
|
||||
$lang->gitlab->project->create = "添加GitLab项目";
|
||||
$lang->gitlab->project->edit = "编辑GitLab项目";
|
||||
$lang->gitlab->project->url = "项目 URL";
|
||||
$lang->gitlab->project->path = "项目标识串";
|
||||
$lang->gitlab->project->description = "项目描述";
|
||||
@@ -104,7 +108,7 @@ $lang->gitlab->project->tagListTips = "用逗号分隔主题。";
|
||||
$lang->gitlab->project->emptyNameError = "项目名称不能为空";
|
||||
$lang->gitlab->project->emptyPathError = "项目标识串不能为空";
|
||||
$lang->gitlab->project->confirmDelete = '确认删除该GitLab项目吗?';
|
||||
$lang->gitlab->project->notbindedError = '还没绑定Gitlab用户,无法修改权限!';
|
||||
$lang->gitlab->project->notbindedError = '还没绑定GitLab用户,无法修改权限!';
|
||||
|
||||
$lang->gitlab->user = new stdclass;
|
||||
$lang->gitlab->user->id = "用户ID";
|
||||
@@ -126,8 +130,8 @@ $lang->gitlab->user->websiteUrl = "网站地址";
|
||||
$lang->gitlab->user->note = "备注";
|
||||
$lang->gitlab->user->createOn = "创建于";
|
||||
$lang->gitlab->user->lastActivity = "上次活动";
|
||||
$lang->gitlab->user->create = "添加Gitlab用户";
|
||||
$lang->gitlab->user->edit = "编辑Gitlab用户";
|
||||
$lang->gitlab->user->create = "添加GitLab用户";
|
||||
$lang->gitlab->user->edit = "编辑GitLab用户";
|
||||
$lang->gitlab->user->emptyError = "不能为空";
|
||||
$lang->gitlab->user->passwordError = "二次密码不一致!";
|
||||
$lang->gitlab->user->bindError = "该用户已经被绑定!";
|
||||
|
||||
@@ -38,7 +38,7 @@ $lang->gitlab->tips = '使用密碼時,請在GitLab全局安全設置中
|
||||
|
||||
$lang->gitlab->placeholder = new stdclass;
|
||||
$lang->gitlab->placeholder->name = '';
|
||||
$lang->gitlab->placeholder->url = "請填寫Gitlab Server首頁的訪問地址,如:https://gitlab.zentao.net。";
|
||||
$lang->gitlab->placeholder->url = "請填寫GitLab Server首頁的訪問地址,如:https://gitlab.zentao.net。";
|
||||
$lang->gitlab->placeholder->token = "請填寫具有admin權限賬戶的access token";
|
||||
|
||||
$lang->gitlab->noImportableIssues = "目前沒有可供導入的issue。";
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class='pull-left'>
|
||||
<?php echo html::backButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', 'btn btn-secondary');?>
|
||||
<?php echo html::linkButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, $this->createLink('gitlab', 'browse'), 'self', '','btn btn-secondary');?>
|
||||
</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'");?>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<div class='pull-left'>
|
||||
<?php echo html::backButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', 'btn btn-secondary');?>
|
||||
<?php echo html::linkButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, $this->createLink('gitlab', 'browse'), 'self', '','btn btn-secondary');?>
|
||||
</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'");?>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<form class='main-form form-ajax' method='post' id='teamForm'>
|
||||
<table class='table table-form'>
|
||||
<table class='table-form'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th><?php echo $lang->gitlab->group->memberName;?></th>
|
||||
@@ -51,7 +51,7 @@
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='6' class='text-center form-actions'>
|
||||
<td colspan='4' class='text-center form-actions'>
|
||||
<?php
|
||||
echo html::submitButton('', '', 'hidden btn btn-wide btn-primary');
|
||||
echo html::commonButton($lang->save, 'onclick="saveMembers()" id="saveBtn"', 'btn btn-wide btn-primary');
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<form class='main-form form-ajax' method='post' id='teamForm'>
|
||||
<table class='table table-form'>
|
||||
<table class='table-form'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th><?php echo $lang->gitlab->group->memberName;?></th>
|
||||
@@ -52,7 +52,7 @@
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan='6' class='text-center form-actions'>
|
||||
<td colspan='4' class='text-center form-actions'>
|
||||
<?php
|
||||
echo html::submitButton('', '', 'hidden btn btn-wide btn-primary');
|
||||
echo html::commonButton($lang->save, 'onclick="saveMembers()" id="saveBtn"', 'btn btn-wide btn-primary');
|
||||
|
||||
@@ -1281,7 +1281,7 @@ $lang->resource->mr->create = 'create';
|
||||
$lang->resource->mr->browse = 'browse';
|
||||
$lang->resource->mr->edit = 'edit';
|
||||
$lang->resource->mr->delete = 'delete';
|
||||
$lang->resource->mr->view = 'view';
|
||||
$lang->resource->mr->view = 'overview';
|
||||
$lang->resource->mr->accept = 'accept';
|
||||
$lang->resource->mr->diff = 'viewDiff';
|
||||
$lang->resource->mr->link = 'linkList';
|
||||
|
||||
@@ -208,7 +208,7 @@ class mr extends control
|
||||
$this->view->compile = $this->loadModel('compile')->getById($MR->compileID);
|
||||
$this->view->compileJob = $MR->jobID ? $this->loadModel('job')->getById($MR->jobID) : false;
|
||||
|
||||
$this->view->title = $this->lang->mr->view;
|
||||
$this->view->title = $this->lang->mr->overview;
|
||||
$this->view->MR = $MR;
|
||||
$this->view->rawMR = isset($rawMR) ? $rawMR : false;
|
||||
$this->view->product = $product;
|
||||
@@ -400,7 +400,10 @@ class mr extends control
|
||||
public function close($MRID)
|
||||
{
|
||||
$MR = $this->mr->getByID($MRID);
|
||||
return $this->send($this->mr->close($MR));
|
||||
$result = $this->mr->close($MR);
|
||||
|
||||
if($result['result'] == 'fali') return $this->send($result);
|
||||
die(js::locate($result['locate'], 'parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ $lang->mr->browse = "Browse";
|
||||
$lang->mr->list = "List";
|
||||
$lang->mr->edit = "Edit";
|
||||
$lang->mr->delete = "Delete";
|
||||
$lang->mr->view = "View";
|
||||
$lang->mr->accept = "Accept";
|
||||
$lang->mr->source = 'source';
|
||||
$lang->mr->target = 'target';
|
||||
|
||||
@@ -7,7 +7,6 @@ $lang->mr->browse = "浏览{$lang->mr->common}";
|
||||
$lang->mr->list = $lang->mr->browse;
|
||||
$lang->mr->edit = "编辑{$lang->mr->common}";
|
||||
$lang->mr->delete = "删除{$lang->mr->common}";
|
||||
$lang->mr->view = "{$lang->mr->common}详情";
|
||||
$lang->mr->accept = "合并请求";
|
||||
$lang->mr->source = '源项目分支';
|
||||
$lang->mr->target = '目标项目分支';
|
||||
|
||||
@@ -6,7 +6,6 @@ $lang->mr->browse = "瀏覽{$lang->mr->common}";
|
||||
$lang->mr->list = $lang->mr->browse;
|
||||
$lang->mr->edit = "編輯{$lang->mr->common}";
|
||||
$lang->mr->delete = "刪除{$lang->mr->common}";
|
||||
$lang->mr->view = "{$lang->mr->common}詳情";
|
||||
$lang->mr->accept = "合併請求";
|
||||
$lang->mr->source = '源項目分支';
|
||||
$lang->mr->target = '目標項目分支';
|
||||
|
||||
+1
-1
@@ -705,7 +705,7 @@ class mrModel extends model
|
||||
public function approve($MR, $action = 'approve', $comment = '')
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$actionID = $this->action->create('mrapproval', $MR->id, $action);
|
||||
$actionID = $this->action->create('mr', $MR->id, $action);
|
||||
|
||||
$oldMR = $MR;
|
||||
if(isset($MR->status) and $MR->status == 'opened')
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
<?php endif;?>
|
||||
<td class='c-actions'>
|
||||
<?php
|
||||
common::printLink('mr', 'view', "mr={$MR->id}", '<i class="icon icon-eye"></i>', '', "title='{$lang->mr->view}' class='btn btn-info'");
|
||||
common::printLink('mr', 'view', "mr={$MR->id}", '<i class="icon icon-eye"></i>', '', "title='{$lang->mr->overview}' class='btn btn-info'");
|
||||
common::printLink('mr', 'edit', "mr={$MR->id}", '<i class="icon icon-edit"></i>', '', "title='{$lang->mr->edit}' class='btn btn-info'");
|
||||
common::printLink('mr', 'diff', "mr={$MR->id}", '<i class="icon icon-review"></i>', '', "title='{$lang->mr->viewDiff}' class='btn btn-info'");
|
||||
common::printLink('mr', 'link', "mr={$MR->id}", '<i class="icon icon-link"></i>', '', "title='{$lang->mr->link}' class='btn btn-info'" . ($MR->linkButton == false ? 'disabled' : ''));
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<div class="btn-toolbar">
|
||||
<?php common::printBack(inlink('browse', '')); ?>
|
||||
<?php $acceptDisabled = ($MR->approvalStatus != 'approved' or ($MR->compileID !=0 and $MR->compileStatus != 'success')) ? ' disabled' : ''; ?>
|
||||
<?php if($rawMR->state == 'opened' and !$rawMR->has_conflicts) echo html::a(inlink('accept', "mr=$MR->id", '', true), '<i class="icon icon-flow"></i> ' . $lang->mr->acceptMR, '', "id='mergeButton' class='btn' $acceptDisabled"); ?>
|
||||
<?php if($rawMR->state == 'opened' and !$rawMR->has_conflicts) echo html::a(inlink('accept', "mr=$MR->id"), '<i class="icon icon-flow"></i> ' . $lang->mr->acceptMR, '', "id='mergeButton' class='btn' $acceptDisabled"); ?>
|
||||
<?php if($rawMR->state == 'opened'): ?>
|
||||
<?php if($rawMR->has_conflicts or ($MR->compileID !=0 and $MR->compileStatus != 'success') or $MR->approvalStatus == 'approved'):?>
|
||||
<?php echo html::a(inlink('approval', "mr=$MR->id&action=approve", '', true), '<i class="icon icon-ok"></i> ' . $lang->mr->approve, '', "id='mergeButton' class='btn iframe showinonlybody' disabled"); ?>
|
||||
@@ -111,7 +111,7 @@
|
||||
<?php echo html::a(inlink('approval', "mr=$MR->id&action=approve", '', true), '<i class="icon icon-ok"></i> ' . $lang->mr->approve, '', "id='mergeButton' class='btn iframe showinonlybody'"); ?>
|
||||
<?php endif;?>
|
||||
<?php echo html::a(inlink('approval', "mr=$MR->id&action=reject", '', true), '<i class="icon icon-bug"></i> ' . $lang->mr->reject, '', "id='mergeButton' class='btn iframe showinonlybody'" . ($MR->approvalStatus == 'rejected' ? 'disabled' : '')); ?>
|
||||
<?php echo html::a(inlink('close', "mr=$MR->id"), '<i class="icon icon-close"></i> ' . $lang->mr->close, '', "id='mergeButton' class='btn'"); ?>
|
||||
<?php common::printIcon('mr', 'close', "mr=$MR->id", $MR, 'button', 'off', 'hiddenwin');?>
|
||||
<?php echo html::a(inlink('edit', "mr=$MR->id"), '<i class="icon icon-edit"></i> ' . str_replace($lang->mr->common, '', $lang->mr->edit), '', "id='mergeButton' class='btn'"); ?>
|
||||
<?php endif;?>
|
||||
<?php if($rawMR->state == 'closed') echo html::a(inlink('reopen', "mr=$MR->id"), '<i class="icon icon-restart"></i> ' . $lang->mr->reopen, '', "id='mergeButton' class='btn'"); ?>
|
||||
|
||||
+19
-13
@@ -530,20 +530,26 @@ class productModel extends model
|
||||
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$output .= "</div></div>";
|
||||
|
||||
$notNormalProduct = (isset($currentProduct->type) and $currentProduct->type != 'normal');
|
||||
$isTrackMethod = ($currentModule == 'story' and $currentMethod == 'track');
|
||||
$isTreeBrowseMethod = ($currentModule == 'tree' and $currentMethod == 'browse');
|
||||
$isShowBranchMethod = (strpos($this->config->product->showBranchMethod, $currentMethod) !== false and $currentModule == 'product') || $isTrackMethod || $isTreeBrowseMethod;
|
||||
if($notNormalProduct and strpos(',testsuite,testreport,', ',' . $currentModule . ',') === false and ($this->app->tab == 'qa' or $isShowBranchMethod))
|
||||
$notNormalProduct = (isset($currentProduct->type) and $currentProduct->type != 'normal');
|
||||
if($notNormalProduct)
|
||||
{
|
||||
$this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$currentProduct->type]);
|
||||
$branches = $this->loadModel('branch')->getPairs($productID, 'all');
|
||||
$branchName = isset($branches[$branch]) ? $branches[$branch] : $branches[0];
|
||||
$dropMenuLink = helper::createLink('branch', 'ajaxGetDropMenu', "objectID=$productID&branch=$branch&module=$currentModule&method=$currentMethod&extra=$extra");
|
||||
$isShowBranch = false;
|
||||
if($currentModule == 'story' and $currentMethod == 'track') $isShowBranch = true;
|
||||
if($currentModule == 'tree' and $currentMethod == 'browse') $isShowBranch = true;
|
||||
if($currentModule == 'product' and strpos($this->config->product->showBranchMethod, $currentMethod) !== false) $isShowBranch = true;
|
||||
if($this->app->tab == 'qa' and strpos(',testsuite,testreport,testtask,', ",$currentModule,") === false) $isShowBranch = true;
|
||||
if($this->app->tab == 'qa' and $currentModule == 'testtask' and strpos(',create,edit,', ",$currentMethod,") === false) $isShowBranch = true;
|
||||
if($isShowBranch)
|
||||
{
|
||||
$this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$currentProduct->type]);
|
||||
$branches = $this->loadModel('branch')->getPairs($productID, 'all');
|
||||
$branchName = isset($branches[$branch]) ? $branches[$branch] : $branches[0];
|
||||
$dropMenuLink = helper::createLink('branch', 'ajaxGetDropMenu', "objectID=$productID&branch=$branch&module=$currentModule&method=$currentMethod&extra=$extra");
|
||||
|
||||
$output .= "<div class='btn-group header-btn'><button id='currentBranch' data-toggle='dropdown' type='button' class='btn'><span class='text'>{$branchName}</span> <span class='caret' style='margin-bottom: -1px'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
|
||||
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$output .= "</div></div>";
|
||||
$output .= "<div class='btn-group header-btn'><button id='currentBranch' data-toggle='dropdown' type='button' class='btn'><span class='text'>{$branchName}</span> <span class='caret' style='margin-bottom: -1px'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
|
||||
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$output .= "</div></div>";
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
@@ -1234,7 +1240,7 @@ class productModel extends model
|
||||
$executionPairs = $executionPairs + $execution->children;
|
||||
continue;
|
||||
}
|
||||
if($this->config->systemMode == 'new') $executionPairs[$execution->id] = $projectPairs[$execution->project] . '/' . $execution->name;
|
||||
if($this->config->systemMode == 'new' and isset($projectPairs[$execution->project])) $executionPairs[$execution->id] = $projectPairs[$execution->project] . '/' . $execution->name;
|
||||
if($this->config->systemMode == 'classic') $executionPairs[$execution->id] = $execution->name;
|
||||
}
|
||||
|
||||
|
||||
@@ -920,6 +920,7 @@ class programplanModel extends model
|
||||
->where('t1.product')->eq($productID)
|
||||
->andWhere('t2.project')->eq($executionID)
|
||||
->andWhere('t2.grade')->eq(1)
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
|
||||
->orderBy('t2.id desc')
|
||||
->fetchPairs();
|
||||
|
||||
@@ -26,3 +26,4 @@ $lang->projectrelease->unlinkStory = "Unlink {$lang->SRCommon}";
|
||||
$lang->projectrelease->unlinkBug = 'Unlink Bug';
|
||||
$lang->projectrelease->export = 'Export as HTML';
|
||||
$lang->projectrelease->browseAction = "Release List";
|
||||
$lang->projectrelease->notify = 'notify';
|
||||
|
||||
@@ -26,3 +26,4 @@ $lang->projectrelease->unlinkStory = "Unlink {$lang->SRCommon}";
|
||||
$lang->projectrelease->unlinkBug = 'Unlink Bug';
|
||||
$lang->projectrelease->export = 'Export as HTML';
|
||||
$lang->projectrelease->browseAction = "Release List";
|
||||
$lang->projectrelease->notify = 'notify';
|
||||
|
||||
@@ -26,3 +26,4 @@ $lang->projectrelease->unlinkStory = "Unlink {$lang->SRCommon}";
|
||||
$lang->projectrelease->unlinkBug = 'Unlink Bug';
|
||||
$lang->projectrelease->export = 'Export HTML';
|
||||
$lang->projectrelease->browseAction = "Release List";
|
||||
$lang->projectrelease->notify = 'notify';
|
||||
|
||||
@@ -26,3 +26,4 @@ $lang->projectrelease->unlinkStory = "Unlink {$lang->SRCommon}";
|
||||
$lang->projectrelease->unlinkBug = 'Unlink Bug';
|
||||
$lang->projectrelease->export = 'Xuất ra HTML';
|
||||
$lang->projectrelease->browseAction = "Release List";
|
||||
$lang->projectrelease->notify = 'notify';
|
||||
|
||||
@@ -26,3 +26,4 @@ $lang->projectrelease->unlinkStory = "移除{$lang->SRCommon}";
|
||||
$lang->projectrelease->unlinkBug = '移除Bug';
|
||||
$lang->projectrelease->export = '导出HTML';
|
||||
$lang->projectrelease->browseAction = "发布列表";
|
||||
$lang->projectrelease->notify = "通知";
|
||||
|
||||
@@ -128,12 +128,12 @@ $lang->repo->logStyles['D'] = 'Delete';
|
||||
$lang->repo->encodingList['utf_8'] = 'UTF-8';
|
||||
$lang->repo->encodingList['gbk'] = 'GBK';
|
||||
|
||||
$lang->repo->scmList['Gitlab'] = 'Gitlab';
|
||||
$lang->repo->scmList['Gitlab'] = 'GitLab';
|
||||
$lang->repo->scmList['Git'] = 'Git';
|
||||
$lang->repo->scmList['Subversion'] = 'SVN';
|
||||
|
||||
$lang->repo->gitlabHost = 'Gitlab Host';
|
||||
$lang->repo->gitlabToken = 'Gitlab Token';
|
||||
$lang->repo->gitlabHost = 'GitLab Host';
|
||||
$lang->repo->gitlabToken = 'GitLab Token';
|
||||
$lang->repo->gitlabProject = 'Project';
|
||||
|
||||
$lang->repo->placeholder = new stdclass;
|
||||
|
||||
@@ -128,7 +128,7 @@ $lang->repo->logStyles['D'] = '删除';
|
||||
$lang->repo->encodingList['utf_8'] = 'UTF-8';
|
||||
$lang->repo->encodingList['gbk'] = 'GBK';
|
||||
|
||||
$lang->repo->scmList['Gitlab'] = 'Gitlab';
|
||||
$lang->repo->scmList['Gitlab'] = 'GitLab';
|
||||
$lang->repo->scmList['Git'] = '本地 Git';
|
||||
$lang->repo->scmList['Subversion'] = 'Subversion';
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ $lang->task->color = 'Color';
|
||||
$lang->task->name = 'Name';
|
||||
$lang->task->type = 'Type';
|
||||
$lang->task->typeAB = 'Type';
|
||||
$lang->task->sync2Gitlab = 'Sync to Gitlab';
|
||||
$lang->task->sync2Gitlab = 'Sync to GitLab';
|
||||
$lang->task->pri = 'Priority';
|
||||
$lang->task->mailto = 'Mailto';
|
||||
$lang->task->estimate = 'Estimates';
|
||||
|
||||
@@ -71,7 +71,7 @@ $lang->task->color = '标题颜色';
|
||||
$lang->task->name = '任务名称';
|
||||
$lang->task->type = '任务类型';
|
||||
$lang->task->typeAB = '类型';
|
||||
$lang->task->sync2Gitlab = '同步到Gitlab';
|
||||
$lang->task->sync2Gitlab = '同步到GitLab';
|
||||
$lang->task->pri = '优先级';
|
||||
$lang->task->mailto = '抄送给';
|
||||
$lang->task->estimate = '最初预计';
|
||||
|
||||
@@ -70,7 +70,7 @@ $lang->task->color = '標題顏色';
|
||||
$lang->task->name = '任務名稱';
|
||||
$lang->task->type = '任務類型';
|
||||
$lang->task->typeAB = '類型';
|
||||
$lang->task->sync2Gitlab = '同步到Gitlab';
|
||||
$lang->task->sync2Gitlab = '同步到GitLab';
|
||||
$lang->task->pri = '優先順序';
|
||||
$lang->task->mailto = '抄送給';
|
||||
$lang->task->estimate = '最初預計';
|
||||
|
||||
@@ -409,7 +409,7 @@ class taskModel extends model
|
||||
$mails[$i]->actionID = $actionID;
|
||||
}
|
||||
|
||||
if(!dao::isError())
|
||||
if(!dao::isError())
|
||||
{
|
||||
$this->loadModel('score')->create('ajax', 'batchCreate');
|
||||
$this->loadModel('kanban')->updateLane($executionID, 'task');
|
||||
@@ -1728,7 +1728,7 @@ class taskModel extends model
|
||||
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
if($oldTask->story) $this->loadModel('story')->setStage($oldTask->story);
|
||||
if($task->status == 'done' && !dao::isError())
|
||||
if($task->status == 'done' && !dao::isError())
|
||||
{
|
||||
$this->loadModel('score')->create('task', 'finish', $taskID);
|
||||
$this->loadModel('kanban')->updateLane($oldTask->execution, 'task');
|
||||
@@ -2164,7 +2164,7 @@ class taskModel extends model
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'task');
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'task', false);
|
||||
|
||||
$taskTeam = $this->dao->select('*')->from(TABLE_TEAM)->where('root')->in(array_keys($tasks))->andWhere('type')->eq('task')->fetchGroup('root');
|
||||
if(!empty($taskTeam))
|
||||
|
||||
@@ -252,7 +252,7 @@ class testtask extends control
|
||||
|
||||
/* Create testtask from testtask of test.*/
|
||||
$productID = $productID ? $productID : key($this->products);
|
||||
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, 0, 'id_desc', $projectID);
|
||||
$executions = empty($productID) ? array() : $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID);
|
||||
$builds = empty($productID) ? array() : $this->loadModel('build')->getProductBuildPairs($productID, 'all', 'notrunk', true);
|
||||
|
||||
$testreports = $this->testtask->getTestReportPairsByBuild($build);
|
||||
|
||||
@@ -23,7 +23,7 @@ function loadProductRelated()
|
||||
*/
|
||||
function loadExecutions(productID)
|
||||
{
|
||||
link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID);
|
||||
link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID + '&branch=');
|
||||
$.get(link, function(data)
|
||||
{
|
||||
if(!data) data = '<select id="execution" name="execution" class="form-control"></select>';
|
||||
|
||||
@@ -1433,7 +1433,7 @@ class testtaskModel extends model
|
||||
echo "</span>";
|
||||
break;
|
||||
case 'title':
|
||||
if(isset($run->branch)) echo "<span class='label label-info label-outline'>{$branches[$run->branch]}</span>";
|
||||
if(!empty($branches)) echo "<span class='label label-badge label-outline'>{$branches[$run->branch]}</span>";
|
||||
if($canView)
|
||||
{
|
||||
if($fromCaseID)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
$config->message->available['xuanxuan']['story'] = $config->message->objectTypes['story'];
|
||||
$config->message->available['xuanxuan']['task'] = $config->message->objectTypes['task'];
|
||||
$config->message->available['xuanxuan']['bug'] = $config->message->objectTypes['bug'];
|
||||
$config->message->available['xuanxuan']['todo'] = $config->message->objectTypes['todo'];
|
||||
$config->message->available['xuanxuan']['release'] = $config->message->objectTypes['release'];
|
||||
$config->message->setting['xuanxuan']['setting'] = $config->message->available['xuanxuan'];
|
||||
$config->message->available['xuanxuan']['story'] = $config->message->objectTypes['story'];
|
||||
$config->message->available['xuanxuan']['task'] = $config->message->objectTypes['task'];
|
||||
$config->message->available['xuanxuan']['bug'] = $config->message->objectTypes['bug'];
|
||||
$config->message->available['xuanxuan']['todo'] = $config->message->objectTypes['todo'];
|
||||
$config->message->setting['xuanxuan']['setting'] = $config->message->available['xuanxuan'];
|
||||
|
||||
Reference in New Issue
Block a user