Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into zentaopms_289
This commit is contained in:
@@ -418,9 +418,11 @@ $config->pipelineTypeList = array('gitlab', 'gogs', 'gitea', 'jenkins', 'sonarqu
|
||||
|
||||
/* Program privs.*/
|
||||
$config->programPriv = new stdclass();
|
||||
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
|
||||
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
|
||||
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
|
||||
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
|
||||
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
|
||||
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
|
||||
$config->programPriv->agileplus = $config->programPriv->scrum;
|
||||
$config->programPriv->waterfallplus = $config->programPriv->waterfall;
|
||||
|
||||
$config->waterfallModules = array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'opportunity', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport');
|
||||
|
||||
|
||||
@@ -260,5 +260,7 @@ INSERT IGNORE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `syst
|
||||
UPDATE `zt_grouppriv` SET `module` = 'testcase' WHERE `module` = 'story' and `method` = 'zeroCase';
|
||||
UPDATE `zt_grouppriv` SET `module` = 'product' WHERE `module` = 'story' and `method` = 'track';
|
||||
|
||||
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) SELECT `group`, 'product', 'requirement' FROM `zt_grouppriv` WHERE `module` = 'product' AND `method` = 'browse';
|
||||
|
||||
ALTER TABLE `zt_job` ADD `lastSyncDate` datetime DEFAULT NULL AFTER `lastTag`;
|
||||
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('*/5', '*', '*', '*', '*', 'moduleName=compile&methodName=syncCompile', '定时同步构建记录', 'zentao', 1, 'normal', '0000-00-00 00:00:00');
|
||||
|
||||
@@ -11,6 +11,25 @@
|
||||
*/
|
||||
class admin extends control
|
||||
{
|
||||
/**
|
||||
* The gogs constructor.
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
|
||||
if(!isset($this->config->global->sn))
|
||||
{
|
||||
$this->loadModel('setting');
|
||||
$this->setting->setItem('system.common.global.sn', $this->setting->computeSN());
|
||||
|
||||
if(!isset($this->config->global)) $this->config->global = new stdclass();
|
||||
$this->config->global->sn = $this->setting->getItem('owner=system&module=common§ion=global&key=sn');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Index page.
|
||||
* @access public
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
.official {justify-content: center;}
|
||||
.official > .panel-title {position: absolute; top: 0px;}
|
||||
.official-img {background-image: url('/static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;}
|
||||
.official-img {background-image: url('static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;}
|
||||
.official-content {flex: 0 0 60%; display: flex; flex-direction: column; padding-left: 10px; padding-top: 15px;}
|
||||
.official-content > .content {color: #838A9D; font-size: 12px; line-height: 22px; padding-top: 6px;}
|
||||
.official-content > .title {color: #313C52; font-size: 13px; line-height: 14px;}
|
||||
|
||||
@@ -85,7 +85,7 @@ $lang->admin->menuList->model['menuOrder']['20'] = 'agileplus';
|
||||
$lang->admin->menuList->model['menuOrder']['25'] = 'waterfallplus';
|
||||
|
||||
$lang->admin->menuList->model['tabMenu']['common']['project'] = array('link' => "{$lang->project->common}|custom|required|module=project", 'alias' => 'set', 'exclude' => 'custom', 'links' => array('custom|set|module=project&field=unitList'));
|
||||
if(helper::hasFeature('waterfall') or helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['common']['stage'] = array('link' => "{$lang->stage->type}|stage|settype|", 'subModule' => 'stage', 'links' => array('stage|browse|'));
|
||||
if(helper::hasFeature('waterfall') or helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['common']['stage'] = array('link' => "{$lang->stage->type}|stage|settype|", 'subModule' => 'stage');
|
||||
$lang->admin->menuList->model['tabMenu']['common']['build'] = array('link' => "{$lang->build->common}|custom|required|module=build", 'alias' => 'set', 'exclude' => 'custom');
|
||||
$lang->admin->menuList->model['tabMenu']['common']['flow'] = array('link' => "{$lang->custom->flow}|custom|flow|", 'divider' => true);
|
||||
$lang->admin->menuList->model['tabMenu']['common']['code'] = array('link' => "{$lang->code}|custom|code|");
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<button class="btn shadow-primary-hover" <?php if($menu['disabled']) echo 'disabled';?> data-link='<?php echo $menu['link'];?>'>
|
||||
<h4 class="flex align-center w-full">
|
||||
<div class="flex align-center">
|
||||
<img src="/static/svg/admin-<?php echo $menuKey;?>.svg"/>
|
||||
<img src="static/svg/admin-<?php echo $menuKey;?>.svg"/>
|
||||
<?php echo $menu['name'];?>
|
||||
</div>
|
||||
<?php echo html::a($config->admin->helpURL[$menuKey], "<i class='icon icon-help'></i> ", '_blank', 'class="text-muted setting-help"');?>
|
||||
@@ -45,7 +45,7 @@
|
||||
<?php foreach($plugins as $plugin):?>
|
||||
<?php $pluginDesc = preg_replace('/[[:cntrl:]]/mu', '', strip_tags($plugin->abstract));?>
|
||||
<div class="plugin-item shadow-primary-hover" data-link='<?php echo $plugin->viewLink;?>'>
|
||||
<a href="<?php echo $plugin->viewLink;?>" class='ext-download' target='_blank'><i class='icon icon-download-alt text-primary bg-primary-100 pd-3'></i></a>
|
||||
<span class='ext-download'><i class='icon icon-download-alt text-primary bg-primary-100 pd-3'></i></span>
|
||||
<h4 class="plug-title" title="<?php echo $plugin->name;?>"><?php echo $plugin->name;?></h4>
|
||||
<p class='extension-desc text-muted' title="<?php echo $pluginDesc;?>"><?php echo $pluginDesc;?></p>
|
||||
</div>
|
||||
@@ -70,7 +70,7 @@
|
||||
<div class="content"> <?php echo $lang->admin->followUsContent?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if(!$bind and !$ignore and common::hasPriv('admin', 'register')):?>
|
||||
<?php if(!$bind and !$ignore and $hasInternet and common::hasPriv('admin', 'register')):?>
|
||||
<div class="panel-link"> <?php echo sprintf($lang->admin->notice->register, html::a(inlink('register'), $lang->admin->registerNotice->submitHere, '', 'class="text-primary"'));?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
|
||||
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = 'QA';
|
||||
$lang->custom->features['devops'] = 'DevOps';
|
||||
$lang->custom->features['kanban'] = 'Kanban';
|
||||
$lang->custom->features['doc'] = 'Doc';
|
||||
$lang->custom->features['report'] = 'Statistics';
|
||||
$lang->custom->features['report'] = $lang->report->common;
|
||||
$lang->custom->features['system'] = 'System';
|
||||
$lang->custom->features['assetlib'] = 'Asset Lib';
|
||||
$lang->custom->features['oa'] = 'Attend';
|
||||
|
||||
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = 'QA';
|
||||
$lang->custom->features['devops'] = 'DevOps';
|
||||
$lang->custom->features['kanban'] = 'Kanban';
|
||||
$lang->custom->features['doc'] = 'Doc';
|
||||
$lang->custom->features['report'] = 'Statistics';
|
||||
$lang->custom->features['report'] = $lang->report->common;
|
||||
$lang->custom->features['system'] = 'System';
|
||||
$lang->custom->features['assetlib'] = 'Asset Lib';
|
||||
$lang->custom->features['oa'] = 'Attend';
|
||||
|
||||
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = 'QA';
|
||||
$lang->custom->features['devops'] = 'DevOps';
|
||||
$lang->custom->features['kanban'] = 'Kanban';
|
||||
$lang->custom->features['doc'] = 'Doc';
|
||||
$lang->custom->features['report'] = 'Statistics';
|
||||
$lang->custom->features['report'] = $lang->report->common;
|
||||
$lang->custom->features['system'] = 'System';
|
||||
$lang->custom->features['assetlib'] = 'Asset Lib';
|
||||
$lang->custom->features['oa'] = 'Attend';
|
||||
|
||||
@@ -266,7 +266,7 @@ $lang->custom->features['qa'] = '测试';
|
||||
$lang->custom->features['devops'] = 'DevOps';
|
||||
$lang->custom->features['kanban'] = '看板';
|
||||
$lang->custom->features['doc'] = '文档';
|
||||
$lang->custom->features['report'] = '统计';
|
||||
$lang->custom->features['report'] = $lang->report->common;
|
||||
$lang->custom->features['system'] = '组织';
|
||||
$lang->custom->features['assetlib'] = '资产库';
|
||||
$lang->custom->features['oa'] = '办公';
|
||||
|
||||
@@ -1091,46 +1091,8 @@ class executionModel extends model
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
/* This stage has a parent stage. */
|
||||
$checkTopStage = $this->programplan->checkTopStage($executionID);
|
||||
$siblingsAllWait = true;
|
||||
if(!$checkTopStage)
|
||||
{
|
||||
/* Check sibling stages are all wait. */
|
||||
foreach($siblingStages as $siblingID => $sibling)
|
||||
{
|
||||
if($siblingID == $executionID) continue;
|
||||
|
||||
if($sibling->status != 'wait')
|
||||
{
|
||||
$siblingsAllWait = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($siblingsAllWait)
|
||||
{
|
||||
/* Actual start or consumed work exists for the parent phase. */
|
||||
$parent = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentID)->fetch();
|
||||
$parentsChildren = $this->dao->select('id')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('path')->like("%,$executionID,%")->andWhere('id')->ne($parentID)->fetchPairs();
|
||||
$parentHasConsumedTasks = $this->dao->select('count(id) as count')->from(TABLE_TASK)->where('deleted')->eq(0)->andWhere('execution')->in($parentsChildren)->andWhere('consumed')->gt(0)->fetch('count');
|
||||
|
||||
$parentStatus = (!helper::isZeroDate($parent->realBegan) or $parentHasConsumedTasks) ? 'doing' : 'wait';
|
||||
if($parent->status == $parentStatus) return '';
|
||||
|
||||
$newParent = $this->buildExecutionByStatus($parentStatus);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($newParent)->where('id')->eq($parentID)->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$changes = common::createChanges($parent, $newParent);
|
||||
$actionType = $parentStatus == 'doing' ? 'started' : 'waitbychild';
|
||||
$actionID = $this->action->create('execution', $parentID, $actionType, '', $actionType);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
if($parent->status == 'wait' and $parentStatus == 'doing') $this->loadModel('common')->syncPPEStatus($parentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
$checkTopStage = $this->programplan->checkTopStage($executionID);
|
||||
if(!$checkTopStage) $this->programplan->computeProgress($executionID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1162,23 +1124,7 @@ class executionModel extends model
|
||||
|
||||
/* This stage has a parent stage. */
|
||||
$checkTopStage = $this->programplan->checkTopStage($executionID);
|
||||
if(!$checkTopStage)
|
||||
{
|
||||
$parent = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentID)->fetch();
|
||||
if($parent->status == 'doing') return '';
|
||||
|
||||
$newParent = $this->buildExecutionByStatus('doing');
|
||||
$this->dao->update(TABLE_EXECUTION)->data($newParent)->where('id')->eq($parentID)->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$changes = common::createChanges($parent, $newParent);
|
||||
$actionID = $this->action->create('execution', $parentID, 'startbychildedit', '', 'startbychildedit');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
if($parent->status == 'wait') $this->loadModel('common')->syncPPEStatus($parentID);
|
||||
}
|
||||
}
|
||||
if(!$checkTopStage) $this->programplan->computeProgress($executionID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1226,38 +1172,8 @@ class executionModel extends model
|
||||
|
||||
/* Suspended: When all child stages at the same level are suspended or closed, the status of the parent stage becomes "suspended". */
|
||||
/* Closed: When all child stages at the same level are closed, the status of the parent stage becomes "closed". */
|
||||
$checkTopStage = $this->programplan->checkTopStage($executionID);
|
||||
$siblingsAllInactived = true;
|
||||
if(!$checkTopStage)
|
||||
{
|
||||
foreach($siblingStages as $siblingID => $sibling)
|
||||
{
|
||||
if($siblingID == $executionID) continue;
|
||||
|
||||
if(strpos($checkedStatus, $sibling->status) !== false)
|
||||
{
|
||||
$siblingsAllInactived = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($siblingsAllInactived)
|
||||
{
|
||||
$parent = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentID)->fetch();
|
||||
if($parent->status == $status) return '';
|
||||
|
||||
$newParent = $this->buildExecutionByStatus($status);
|
||||
$this->dao->update(TABLE_EXECUTION)->data($newParent)->where('id')->eq($parentID)->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$changes = common::createChanges($parent, $newParent);
|
||||
$actionType = $status == 'suspended' ? 'suspendbychild' : 'closebychild';
|
||||
$actionID = $this->action->create('execution', $parentID, $actionType, '', $actionType);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
$checkTopStage = $this->programplan->checkTopStage($executionID);
|
||||
if(!$checkTopStage) $this->programplan->computeProgress($executionID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php if(isonlybody()):?>
|
||||
<style>#importTaskForm .table-footer .pager {z-index: 105;}</style>
|
||||
<?php endif;?>
|
||||
<?php js::set('isonlybody', isonlybody());?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='pull-left btn-toolbar'>
|
||||
|
||||
@@ -1511,16 +1511,7 @@ class programplanModel extends model
|
||||
{
|
||||
if($parent->status != 'wait')
|
||||
{
|
||||
$newParent = new stdclass();
|
||||
$newParent->status = 'wait';
|
||||
$newParent->realBegan = '';
|
||||
$newParent->closedDate = '';
|
||||
$newParent->closedBy = '';
|
||||
$newParent->canceledDate = '';
|
||||
$newParent->canceledBy = '';
|
||||
$newParent->suspendedDate = '';
|
||||
$newParent->lastEditedBy = $this->app->user->account;
|
||||
$newParent->lastEditedDate = helper::now();
|
||||
$newParent = $this->execution->buildExecutionByStatus('wait');
|
||||
$parentAction = 'waitbychild';
|
||||
}
|
||||
}
|
||||
@@ -1528,12 +1519,7 @@ class programplanModel extends model
|
||||
{
|
||||
if($parent->status != 'closed')
|
||||
{
|
||||
$newParent = new stdclass();
|
||||
$newParent->status = 'closed';
|
||||
$newParent->closedDate = helper::now();
|
||||
$newParent->closedBy = $this->app->user->account;
|
||||
$newParent->lastEditedBy = $this->app->user->account;
|
||||
$newParent->lastEditedDate = helper::now();
|
||||
$newParent = $this->execution->buildExecutionByStatus('closed');
|
||||
$parentAction = 'closedbychild';
|
||||
}
|
||||
}
|
||||
@@ -1541,11 +1527,7 @@ class programplanModel extends model
|
||||
{
|
||||
if($parent->status != 'suspended')
|
||||
{
|
||||
$newParent = new stdclass();
|
||||
$newParent->status = 'suspended';
|
||||
$newParent->suspendedDate = helper::now();
|
||||
$newParent->lastEditedBy = $this->app->user->account;
|
||||
$newParent->lastEditedDate = helper::now();
|
||||
$newParent = $this->execution->buildExecutionByStatus('suspended');
|
||||
$parentAction = 'suspendedbychild';
|
||||
}
|
||||
}
|
||||
@@ -1553,16 +1535,7 @@ class programplanModel extends model
|
||||
{
|
||||
if($parent->status != 'doing')
|
||||
{
|
||||
$newParent = new stdclass();
|
||||
$newParent->status = 'doing';
|
||||
$newParent->realBegan = helper::today();
|
||||
$newParent->closedDate = '';
|
||||
$newParent->closedBy = '';
|
||||
$newParent->canceledDate = '';
|
||||
$newParent->canceledBy = '';
|
||||
$newParent->suspendedDate = '';
|
||||
$newParent->lastEditedBy = $this->app->user->account;
|
||||
$newParent->lastEditedDate = helper::now();
|
||||
$newParent = $this->execution->buildExecutionByStatus('doing');
|
||||
$parentAction = $parent->status == 'wait' ?'startbychildstart' : 'startbychild' . $action;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,6 +414,9 @@ function toggleSelectTestStory()
|
||||
$('.colorpicker').css('right', '0');
|
||||
$('#dataform .table-form>tbody>tr>th').css('width', '130px');
|
||||
$('[lang^="zh-"] #dataform .table-form>tbody>tr>th').css('width', '120px');
|
||||
|
||||
$('[name^=multiple]').attr('checked', false);
|
||||
showTeamMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -361,12 +361,7 @@ $(function()
|
||||
{
|
||||
var menuModule = task.nav.menuModule || task.nav['module'];
|
||||
var $navbar = $$('#navbar');
|
||||
var adminMenu = false;
|
||||
if(!$navbar.find('li').length)
|
||||
{
|
||||
adminMenu = true;
|
||||
$navbar = $$('.settings-list');
|
||||
}
|
||||
if(task.nav.app == 'admin') $navbar = $$('.settings-list');
|
||||
var $navbarItem = $navbar.find('[data-id="' + menuModule + '"]');
|
||||
var targetPageTip = lang.targetPageTip.replace('%s', task.nav.targetPageName || lang.target);
|
||||
if($navbarItem.length && !$navbarItem.hasClass('active'))
|
||||
|
||||
@@ -8184,7 +8184,7 @@ class upgradeModel extends model
|
||||
->fetchAll();
|
||||
foreach($typeList as $type)
|
||||
{
|
||||
$langFile = $this->app->getModuleRoot() . DS . 'stage' . DS . 'lang' . DS . $type->lang . '.php';
|
||||
$langFile = $this->app->getModuleRoot() . DS . 'stage' . DS . 'lang' . DS . ($type->lang == 'all' ? $this->app->clientLang : $type->lang) . '.php';
|
||||
if(is_file($langFile)) include $langFile;
|
||||
|
||||
$this->dao->replace(TABLE_LANG)
|
||||
|
||||
Reference in New Issue
Block a user