Merge branch 'master' into 'sprint/208_liumengyi_58561'

# Conflicts:
#   db/update17.1.sql
This commit is contained in:
王怡栋
2022-06-28 05:08:18 +00:00
110 changed files with 770 additions and 319 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
<?php
echo html::a($this->createLink('admin', 'safe'), $lang->admin->safe->set);
echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak, '', "class='active'");
echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting);
if(common::hasPriv('admin', 'resetPWDSetting')) echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting);
?>
</div>
</div>
+1 -1
View File
@@ -25,7 +25,7 @@
<div class='list-group'>
<?php
echo html::a($this->createLink('admin', 'safe'), $lang->admin->safe->set);
echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak);
if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak);
echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting, '', "class='active'");
?>
</div>
+2 -2
View File
@@ -23,8 +23,8 @@
<div class='list-group'>
<?php
echo html::a($this->createLink('admin', 'safe'), $lang->admin->safe->set, '', "class='active'");
echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak);
echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting);
if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak);
if(common::hasPriv('admin', 'resetPWDSetting')) echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting);
?>
</div>
</div>
+116 -38
View File
@@ -553,14 +553,10 @@ class bug extends control
$moduleOwner = $this->bug->getModuleOwner($moduleID, $productID);
/* Set team members of the latest execution as assignedTo list. */
$productMembers = $this->bug->getProductMemberPairs($productID);
/* Get all project team members linked with this product. */
$productMembers = $this->bug->getProductMemberPairs($productID, $branch);
$productMembers = array_filter($productMembers);
if(empty($productMembers)) $productMembers = $this->view->users;
if($assignedTo and !isset($productMembers[$assignedTo]))
{
$user = $this->loadModel('user')->getById($assignedTo);
if($user) $productMembers[$assignedTo] = $user->realname;
}
$moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, ($branch === 'all' or !isset($branches[$branch])) ? 0 : $branch);
if(empty($moduleOptionMenu)) return print(js::locate(helper::createLink('tree', 'browse', "productID=$productID&view=story")));
@@ -577,7 +573,7 @@ class bug extends control
if($projectID)
{
$project = $this->loadModel('project')->getByID($projectID);
if(empty($bugID) or $this->app->tab != 'qa') $projects = array($projectID => $project->name);
if(empty($bugID) or $this->app->tab != 'qa') $projects += array($projectID => $project->name);
}
}
elseif($projectID)
@@ -1090,6 +1086,22 @@ class bug extends control
$moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $bug->branch);
if(!isset($moduleOptionMenu[$bug->module])) $moduleOptionMenu += $this->tree->getModulesName($bug->module);
/* Get assigned to member. */
if($bug->execution)
{
$assignedToList = $this->user->getTeamMemberPairs($bug->execution, 'execution');
}
elseif($bug->project)
{
$assignedToList = $this->loadModel('project')->getTeamMemberPairs($bug->project);
}
else
{
$assignedToList = $this->bug->getProductMemberPairs($bug->product, $bug->branch);
$assignedToList = array_filter($assignedToList);
if(empty($assignedToList)) $assignedToList = $this->user->getPairs('devfirst|noclosed');
}
$this->view->bug = $bug;
$this->view->productID = $productID;
$this->view->product = $product;
@@ -1105,6 +1117,7 @@ class bug extends control
$this->view->tasks = $this->task->getExecutionTaskPairs($bug->execution);
$this->view->testtasks = $this->loadModel('testtask')->getPairs($bug->product, $bug->execution, $bug->testtask);
$this->view->users = $this->user->getPairs('', "$bug->assignedTo,$bug->resolvedBy,$bug->closedBy,$bug->openedBy");
$this->view->assignedToList = $assignedToList;
$this->view->openedBuilds = $openedBuilds;
$this->view->resolvedBuilds = array('' => '') + $openedBuilds + $oldResolvedBuild;
$this->view->actions = $this->action->getList('bug', $bugID);
@@ -1234,35 +1247,94 @@ class bug extends control
$this->view->customFields = $customFields;
$this->view->showFields = $this->config->bug->custom->batchEditFields;
/* Set users. */
$appendUsers = array();
$branchIdList = array();
$projectIdList = array();
$executionIdList = array();
foreach($bugs as $bug)
{
$appendUsers[$bug->assignedTo] = $bug->assignedTo;
$appendUsers[$bug->resolvedBy] = $bug->resolvedBy;
$projectIdList[$bug->project] = $bug->project;
$executionIdList[$bug->execution] = $bug->execution;
$branchIdList[$bug->product][$bug->branch] = $bug->branch;
if(!isset($modules[$bug->product][$bug->branch])) $modules[$bug->product][$bug->branch] = $modules[$bug->product][0] + $this->tree->getModulesName($bug->module);
}
$users = $this->user->getPairs('devfirst', $appendUsers, $this->config->maxCount);
/* Get assigned to member. */
$this->loadModel('project');
$this->loadModel('execution');
$productMembers = array();
$projectMembers = array();
$executionMembers = array();
if($productID)
{
$branchList = zget($branchIdList, $productID, array());
foreach($branchList as $branchID)
{
$members = $this->bug->getProductMemberPairs($productID, $branchID);
$productMembers[$productID][$branchID] = array_filter($members);
}
}
else
{
foreach($productIdList as $id)
{
$branchList = zget($branchIdList, $id, array());
foreach($branchList as $branchID)
{
$members = $this->bug->getProductMemberPairs($id, $branchID);
$productMembers[$id][$branchID] = array_filter($members);
}
}
}
$projectMemberGroup = $this->project->getTeamMemberGroup($projectIdList);
$projectMembers = array();
foreach($projectIdList as $projectID)
{
$projectTeam = zget($projectMemberGroup, $projectID, array());
if(empty($projectTeam)) $projectMembers[$projectID] = array();
foreach($projectTeam as $user)
{
$projectMembers[$projectID][$user->account] = $user->realname;
}
}
$executionMemberGroup = $this->execution->getMembersByIdList($executionIdList);
$executionMembers = array();
foreach($executionIdList as $executionID)
{
$executionTeam = zget($executionMemberGroup, $executionID, array());
if(empty($executionTeam)) $executionMemberGroup[$executionID] = array();
foreach($executionTeam as $user)
{
$executionMembers[$executionID][$user->account] = $user->realname;
}
}
/* Set users. */
$users = $this->user->getPairs('devfirst', '', $this->config->maxCount);
$users = array('' => '', 'ditto' => $this->lang->bug->ditto) + $users;
/* Assign. */
$this->view->position[] = $this->lang->bug->common;
$this->view->position[] = $this->lang->bug->batchEdit;
$this->view->productID = $productID;
$this->view->branchProduct = $branchProduct;
$this->view->severityList = array('ditto' => $this->lang->bug->ditto) + $this->lang->bug->severityList;
$this->view->typeList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->typeList;
$this->view->priList = array('0' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->priList;
$this->view->resolutionList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->resolutionList;
$this->view->statusList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->statusList;
$this->view->osList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->osList;
$this->view->browserList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->browserList;
$this->view->bugs = $bugs;
$this->view->branch = $branch;
$this->view->users = $users;
$this->view->modules = $modules;
$this->view->branchTagOption = $branchTagOption;
$this->view->productID = $productID;
$this->view->branchProduct = $branchProduct;
$this->view->severityList = array('ditto' => $this->lang->bug->ditto) + $this->lang->bug->severityList;
$this->view->typeList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->typeList;
$this->view->priList = array('0' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->priList;
$this->view->resolutionList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->resolutionList;
$this->view->statusList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->statusList;
$this->view->osList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->osList;
$this->view->browserList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->browserList;
$this->view->bugs = $bugs;
$this->view->branch = $branch;
$this->view->users = $users;
$this->view->productMembers = $productMembers;
$this->view->projectMembers = $projectMembers;
$this->view->executionMembers = $executionMembers;
$this->view->modules = $modules;
$this->view->branchTagOption = $branchTagOption;
$this->display();
}
@@ -1320,17 +1392,20 @@ class bug extends control
}
}
if($this->app->tab == 'project')
/* Get assigned to member. */
if($bug->execution)
{
$users = $this->user->getTeamMemberPairs($bug->project, 'project', 'nodeleted', $bug->assignedTo);
$users = $this->user->getTeamMemberPairs($bug->execution, 'execution');
}
elseif($this->app->tab == 'execution')
elseif($bug->project)
{
$users = $this->user->getTeamMemberPairs($bug->execution, 'execution', 'nodeleted', $bug->assignedTo);
$users = $this->loadModel('project')->getTeamMemberPairs($bug->project);
}
else
{
$users = $this->user->getPairs('noclosed', $bug->assignedTo);
$users = $this->bug->getProductMemberPairs($bug->product, $bug->branch);
$users = array_filter($users);
if(empty($users)) $users = $this->user->getPairs('devfirst|noclosed');
}
$this->view->title = $this->products[$bug->product] . $this->lang->colon . $this->lang->bug->assignedTo;
@@ -2029,7 +2104,7 @@ class bug extends control
*/
public function ajaxLoadAssignedTo($executionID, $selectedUser = '')
{
$executionMembers = $this->user->getTeamMemberPairs($executionID, 'execution', '', $selectedUser);
$executionMembers = $this->user->getTeamMemberPairs($executionID, 'execution');
$execution = $this->loadModel('execution')->getByID($executionID);
if(empty($selectedUser)) $selectedUser = $execution->QD;
@@ -2351,12 +2426,15 @@ class bug extends control
*
* @param int $productID
* @param string $selectedUser
* @param int $branchID
* @access public
* @return string
*/
public function ajaxGetProductMembers($productID, $selectedUser = '')
public function ajaxGetProductMembers($productID, $selectedUser = '', $branchID = '')
{
$productMembers = $this->bug->getProductMemberPairs($productID);
$productMembers = $this->bug->getProductMemberPairs($productID, $branchID);
$productMembers = array_filter($productMembers);
if(empty($productMembers)) $productMembers = $this->loadModel('user')->getPairs('devfirst|noclosed');
return print(html::select('assignedTo', $productMembers, $selectedUser, 'class="form-control"'));
}
@@ -2365,7 +2443,7 @@ class bug extends control
* Ajax get project team members.
*
* @param int $projectID
* @param string $$selectedUser
* @param string $selectedUser
* @access public
* @return string
*/
+39 -4
View File
@@ -130,6 +130,7 @@ function loadBranch()
loadProductBuilds(productID);
loadProductplans(productID);
loadProductStories(productID);
loadProductMembers(productID);
}
/**
@@ -333,12 +334,44 @@ function loadProductExecutions(productID, projectID = 0)
$(this).find('select').chosen();
if(typeof(bugExecution) == 'string' && systemMode != 'classic') $('#executionIdBox').prepend("<span class='input-group-addon' id='executionBox' style='border-left-width: 0px;'>" + bugExecution + "</span>");
if(required) $(this).find('#execution_chosen').addClass('required');
if(page != 'edit') changeAssignedTo(projectID);
changeAssignedTo(projectID);
});
projectID != 0 ? loadProjectBuilds(projectID) : loadProductBuilds(productID);
}
/**
* Ajax change execution name.
*
* @param int $projectID
* @access public
* @return void
*/
function changeAssignedTo(projectID)
{
if(parseInt(projectID))
{
loadProjectTeamMembers(projectID);
if(page == 'create')
{
var link = createLink('bug', 'ajaxGetExecutionLang', 'projectID=' + projectID);
$.post(link, function(executionLang)
{
$('#executionBox').html(executionLang);
})
}
}
else if($('#execution').val() != 0)
{
loadAssignedTo($('#execution').val());
}
else
{
var productID = $('#product').val();
loadProductMembers(productID);
}
}
/**
* Load executions of product and project.
*
@@ -441,13 +474,13 @@ function loadExecutionRelated(executionID)
}
else
{
var currentProjectID = $('#project').val();
var currentProjectID = $('#project').val() == 'undefined' ? 0 : $('#project').val();
var currentProductID = $('#product').val();
$('#taskIdBox').innerHTML = '<select id="task"></select>'; // Reset the task.
loadProductStories(currentProductID);
loadTestTasks(currentProductID);
if(typeof(currentProjectID) == 'undefined')
if(currentProjectID == 0)
{
loadProductMembers(currentProductID);
}
@@ -593,7 +626,8 @@ function loadExecutionBuilds(executionID, num)
*/
function loadProductMembers(productID)
{
link = createLink('bug', 'ajaxGetProductMembers', 'productID=' + productID + '&selectedUser=' + $('#assignedTo').val());
var branchID = $('#branch').val() == undefined ? '' : $('#branch').val();
var link = createLink('bug', 'ajaxGetProductMembers', 'productID=' + productID + '&selectedUser=' + $('#assignedTo').val() + '&branchID=' + branchID);
$.get(link, function(data)
{
if(!data) data = '<select id="assignedTo" name="assignedTo" class="form-control"></select>';
@@ -678,6 +712,7 @@ function loadProductBranches(productID, param)
loadProductProjects(productID);
loadProductplans(productID);
loadProductStories(productID);
loadProductMembers(productID);
})
}
-28
View File
@@ -125,34 +125,6 @@ $(function()
});
});
/**
* Ajax change execution name.
*
* @param int $projectID
* @access public
* @return void
*/
function changeAssignedTo(projectID)
{
if(parseInt(projectID))
{
loadProjectTeamMembers(projectID);
var link = createLink('bug', 'ajaxGetExecutionLang', 'projectID=' + projectID);
$.post(link, function(executionLang)
{
$('#executionBox').html(executionLang);
})
}
else if($('#execution').val() != 0)
{
loadAssignedTo($('#execution').val());
}
else
{
setAssignedTo();
}
}
$(window).unload(function(){
if(blockID) window.parent.refreshBlock($('#block' + blockID));
});
+5 -2
View File
@@ -460,6 +460,8 @@ class bugModel extends model
echo(js::alert($this->lang->bug->executionAccessDenied));
$loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login";
if(strpos($this->server->http_referer, $loginLink) !== false) return print(js::locate(helper::createLink('bug', 'index', '')));
if($this->app->tab == 'my') print(js::reload('parent'));
return print(js::locate('back'));
}
}
@@ -1898,14 +1900,15 @@ class bugModel extends model
* get Product member pairs.
*
* @param int $productID
* @param int $branchID
* @access public
* @return void
*/
public function getProductMemberPairs($productID)
public function getProductMemberPairs($productID, $branchID = '')
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getTeamMembersPairs();
$projects = $this->loadModel('product')->getProjectPairsByProduct($productID);
$projects = $this->loadModel('product')->getProjectPairsByProduct($productID, $branchID);
$users = $this->dao->select("t2.id, t2.account, t2.realname")->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account = t2.account')
+21 -1
View File
@@ -102,7 +102,27 @@
<?php endif;?>
<td><?php echo html::select("modules[$bugID]", isset($modules[$bug->product][$bug->branch]) ? $modules[$bug->product][$bug->branch] : array(0 => '/'), $bug->module, "class='form-control picker-select' data-drop-width='auto'");?></td>
<td class='<?php echo zget($visibleFields, 'productplan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plans[$bugID]", $plans, $bug->plan, "class='form-control picker-select' data-drop-width='auto'");?></td>
<td class='<?php echo zget($visibleFields, 'assignedTo', ' hidden')?>' style='overflow:visible'><?php echo html::select("assignedTos[$bugID]", $users, $bug->assignedTo, "class='form-control picker-select' data-drop-width='auto'");?></td>
<?php
$assignedToList = array();
if($bug->execution)
{
$assignedToList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $executionMembers[$bug->execution];
}
elseif($bug->project)
{
$assignedToList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $projectMembers[$bug->project];
}
else
{
$assignedToList = $productMembers[$bug->product][$bug->branch];
if(empty($assignedToList))
{
$assignedToList = $users;
unset($assignedToList['closed']);
}
}
?>
<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 <?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>
+3
View File
@@ -490,6 +490,9 @@ $(function(){$('#bugForm').table();})
<?php if(isset($config->qa->homepage) and $config->qa->homepage != 'browse' and $config->global->flow == 'full'):?>
$(function(){$('#modulemenu .nav li:last').after("<li class='right'><a style='font-size:12px' href='javascript:setHomepage(\"qa\", \"browse\")'><i class='icon icon-cog'></i> <?php echo $lang->homepage?></a></li>")});
<?php endif;?>
<?php if(count($bugs) <= 2):?>
$('#bugForm .table-footer .table-actions #assignedTo').closest('.btn-group.dropup').removeClass('dropup').addClass('dropdown');
<?php endif;?>
function handleLinkButtonClick()
{
var xxcUrl = "xxc:openInApp/zentao-integrated/" + encodeURIComponent(window.location.href.replace(/.display=card/, '').replace(/\.xhtml/, '.html'));
+1 -1
View File
@@ -153,7 +153,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
<th><?php echo $lang->bug->assignedTo;?></th>
<td>
<div class='input-group'>
<?php echo html::select('assignedTo', $users, $bug->assignedTo, "class='form-control chosen'");?>
<?php echo html::select('assignedTo', $assignedToList, $bug->assignedTo, "class='form-control chosen'");?>
<span class='input-group-btn'><?php echo html::commonButton($lang->bug->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?></span>
</div>
</td>
+1 -1
View File
@@ -114,7 +114,7 @@ tbody tr td:first-child input {display: none;}
}
else
{
echo '<a>' . $story->title . '</a>';
echo $story->title;
}
?>
</td>
+1
View File
@@ -81,6 +81,7 @@ $lang->retrack = 'Retrack';
$lang->whitelist = 'Weiße Liste';
$lang->globalSetting = 'Global Setting';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
+1
View File
@@ -81,6 +81,7 @@ $lang->retrack = 'Retrack';
$lang->whitelist = 'Access whitelist';
$lang->globalSetting = 'Global Setting';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
+1
View File
@@ -81,6 +81,7 @@ $lang->retrack = 'Réduire';
$lang->whitelist = 'Liste blanche';
$lang->globalSetting = 'Global Setting';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
+3
View File
@@ -491,6 +491,9 @@ $lang->admin->menu->system = array('link' => "{$lang->admin->system}|backup|i
$lang->admin->menu->model['dropMenu'] = new stdclass();
$lang->admin->menu->model['dropMenu']->allModel = array('link' => "{$lang->globalSetting}|custom|browsestoryconcept|", 'subModule' => 'measurement,report,sqlbuilder,subject,custom,meetingroom,baseline');
if($config->edition == 'max') $lang->admin->menu->model['dropMenu']->scrum = array('link' => "{$lang->scrumModel}|auditcl|scrumbrowse|processID=0&browseType=scrum", 'subModule' => 'auditcl,process,activity,zoutput,classify,');
if($config->systemMode == 'new')
{
$lang->admin->menu->model['dropMenu']->waterfall = array('link' => "{$lang->waterfallModel}|stage|setType|", 'subModule' => 'stage,auditcl,cmcl,process,activity,zoutput,classify,reviewcl,reviewsetting');
+1
View File
@@ -81,6 +81,7 @@ $lang->retrack = '收起';
$lang->whitelist = '访问白名单';
$lang->globalSetting = '全局设置';
$lang->waterfallModel = '瀑布模型';
$lang->scrumModel = '敏捷模型';
$lang->all = '所有';
$lang->viewDetails = '查看详情';
+1 -1
View File
@@ -4,7 +4,7 @@ $config->custom->canAdd['story'] = 'reasonList,sourceList,priList,categoryLis
$config->custom->canAdd['task'] = 'priList,typeList,reasonList';
$config->custom->canAdd['bug'] = 'priList,severityList,osList,browserList,typeList,resolutionList';
$config->custom->canAdd['testcase'] = 'priList,typeList,stageList,resultList,statusList';
$config->custom->canAdd['testtask'] = 'priList';
$config->custom->canAdd['testtask'] = 'priList,typeList';
$config->custom->canAdd['todo'] = 'priList,typeList';
$config->custom->canAdd['user'] = 'roleList';
$config->custom->canAdd['block'] = '';
+1
View File
@@ -166,6 +166,7 @@ $lang->custom->testcase->fields['review'] = 'Review Required';
$lang->custom->testtask = new stdClass();
$lang->custom->testtask->fields['priList'] = 'Priority';
$lang->custom->testtask->fields['typeList'] = 'Type';
$lang->custom->testtask->fields['statusList'] = 'Status';
$lang->custom->todo = new stdClass();
+1
View File
@@ -166,6 +166,7 @@ $lang->custom->testcase->fields['review'] = 'Need Review';
$lang->custom->testtask = new stdClass();
$lang->custom->testtask->fields['priList'] = 'Priority';
$lang->custom->testtask->fields['typeList'] = 'Type';
$lang->custom->testtask->fields['statusList'] = 'Status';
$lang->custom->todo = new stdClass();
+1
View File
@@ -166,6 +166,7 @@ $lang->custom->testcase->fields['review'] = 'Validation Requise';
$lang->custom->testtask = new stdClass();
$lang->custom->testtask->fields['priList'] = 'Priorité';
$lang->custom->testtask->fields['typeList'] = 'Type';
$lang->custom->testtask->fields['statusList'] = 'Statut';
$lang->custom->todo = new stdClass();
+1
View File
@@ -166,6 +166,7 @@ $lang->custom->testcase->fields['review'] = '评审流程';
$lang->custom->testtask = new stdClass();
$lang->custom->testtask->fields['priList'] = '优先级';
$lang->custom->testtask->fields['typeList'] = '测试类型';
$lang->custom->testtask->fields['statusList'] = '状态';
$lang->custom->todo = new stdClass();
+11 -2
View File
@@ -860,6 +860,7 @@ class doc extends control
if($doclib->acl == 'open') return print(html::select('groups[]', $groups, $selectedGroup, "class='form-control picker-select' multiple $dropDirection"));
if($doclib->acl == 'default') return print(html::select('groups[]', $groups, $selectedGroup, "class='form-control picker-select' multiple $dropDirection"));
if($doclib->acl == 'private') echo 'private';
return false;
}
@@ -876,7 +877,15 @@ class doc extends control
}
if($doclib->acl == 'open') return print(html::select('users[]', $users, $selectedUser, "multiple class='form-control picker-select' $dropDirection"));
if($doclib->acl == 'default') return print(html::select('users[]', $users, $selectedUser, "multiple class='form-control picker-select' $dropDirection"));
if($doclib->acl == 'private') echo 'private';
if($doclib->acl == 'private' and $doclib->type == 'project')
{
echo 'project';
}
else
{
echo 'private';
}
return false;
}
@@ -891,7 +900,7 @@ class doc extends control
$selectedUser = $whitelist;
}
return print(html::select('users[]', $users, $selectedUser, "class='form-control chosen' multiple"));
return print(html::select('users[]', $users, $selectedUser, "class='form-control picker-select' multiple"));
}
/**
+3 -2
View File
@@ -41,6 +41,7 @@ function toggleAcl(acl, type)
else
{
$('#whiteListBox').addClass('hidden');
if(type == 'doc') loadWhitelist(libID);
}
if(type == 'lib')
@@ -57,8 +58,8 @@ function toggleAcl(acl, type)
$.get(link, function(users)
{
$('#users').replaceWith(users);
$('#users_chosen').remove();
$('#users').chosen();
$('#user').next(' .picker').remove();
$('#users').picker();
})
}
}
+11 -5
View File
@@ -117,9 +117,9 @@ function loadWhitelist(libID)
{
if(groups != 'private')
{
$('#groups').replaceWith(groups);
$('#groups_chosen').remove();
$('#groups').picker();
$('#groups').replaceWith(groups);
$('#groups').next('.picker').remove();
$('#groups').picker();
}
});
@@ -132,14 +132,20 @@ function loadWhitelist(libID)
$('#whiteListBox').addClass('hidden');
$('#aclprivate').prop('checked', true);
}
else if(users == 'project')
{
$('#aclprivate').parent('.radio-inline').addClass('hidden');
$('#aclcustom').parent('.radio-inline').addClass('hidden');
$('#whiteListBox').addClass('hidden');
$('#aclopen').prop('checked', true);
}
else
{
$('#aclopen').parent('.radio-inline').removeClass('hidden');
$('#aclcustom').parent('.radio-inline').removeClass('hidden');
$('#users').replaceWith(users);
$('#users_chosen').remove();
$('#whiteListBox .picker').remove();
$('#users').next('.picker').remove();
$('#users').picker();
}
});
+4 -5
View File
@@ -141,9 +141,9 @@ function loadWhitelist(libID)
{
if(groups != 'private')
{
$('#groups').replaceWith(groups);
$('#groups_chosen').remove();
$('#groups').picker();
$('#groups').replaceWith(groups);
$('#groups').next('.picker').remove();
$('#groups').picker();
}
});
@@ -162,8 +162,7 @@ function loadWhitelist(libID)
$('#aclcustom').parent('.radio-inline').removeClass('hidden');
$('#users').replaceWith(users);
$('#users_chosen').remove();
$('#whiteListBox .picker').remove();
$('#user').next('.picker').remove();
$('#users').picker();
}
});
+1 -1
View File
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
?>
<?php js::set('maxCount', $this->config->maxCount);?>
<?php if($docType != '' and strpos($config->doc->officeTypes, $docType) !== false):?>
<?php include '../../common/view/header.lite.html.php';?>
<div id="mainContent" class="main-content">
@@ -109,6 +108,7 @@ $("a[href^='###']").click(function()
<th><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'default' ? 'open' : $lib->acl;?>
<?php $acl = ($lib->type == 'project' and $acl == 'private') ? 'open' : $acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'");?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></span>
</td>
-1
View File
@@ -17,7 +17,6 @@
<?php js::set('confirmUpdateContent', $lang->doc->confirmUpdateContent);?>
<?php js::set('docID', $doc->id);?>
<?php js::set('draft', $doc->draft);?>
<?php js::set('maxCount', $this->config->maxCount);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
+6 -1
View File
@@ -745,6 +745,7 @@ class execution extends control
/* Save session. */
$this->app->session->set('storyList', $this->app->getURI(true), 'execution');
$this->app->session->set('executionStoryList', $this->app->getURI(true), 'execution');
/* Process the order by field. */
if(!$orderBy) $orderBy = $this->cookie->executionStoryOrder ? $this->cookie->executionStoryOrder : 'pri';
@@ -2608,6 +2609,8 @@ class execution extends control
$productPairs = $this->loadModel('product')->getProductPairsByProject($executionID);
if($productPairs) $productID = key($productPairs);
$this->app->session->set('executionStoryList', $this->app->getURI(true), 'execution');
$this->view->title = $this->lang->execution->storyKanban;
$this->view->position[] = html::a($this->createLink('execution', 'story', "executionID=$executionID"), $execution->name);
$this->view->position[] = $this->lang->execution->storyKanban;
@@ -2910,8 +2913,9 @@ class execution extends control
/* Get projects, executions and products. */
$object = $this->project->getByID($objectID, $this->app->tab == 'project' ? 'project' : 'sprint,stage,kanban');
$products = $this->product->getProducts($objectID);
$browseLink = $this->createLink($this->app->tab == 'project' ? 'projectstory' : 'execution', 'story', "objectID=$objectID");
$queryID = ($browseType == 'bySearch') ? (int)$param : 0;
$browseLink = $this->session->executionStoryList;
if($this->app->tab == 'project') $browseLink = $this->createLink('projectstory', 'story', "objectID=$objectID");
$this->session->set('storyList', $this->app->getURI(true), $this->app->tab); // Save session.
@@ -3034,6 +3038,7 @@ class execution extends control
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->branchGroups = $branchGroups;
$this->view->browseLink = $browseLink;
$this->display();
}
+2
View File
@@ -8,3 +8,5 @@ th.c-deadline {text-align: center;}
.c-left {text-align: right;}
.table-footer {z-index: 1;}
.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;}
+1 -1
View File
@@ -20,7 +20,7 @@
<span class='btn btn-link btn-active-text'><span class='text'><?php echo $lang->execution->linkStory;?></span></span>
</div>
<div class='btn-toolbar pull-right'>
<?php common::printBack($this->createLink($this->app->rawModule, 'story', "objectID=$objectID"), 'btn btn-link');?>
<?php echo html::a($browseLink, '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-primary'");?>
</div>
</div>
<div id="mainContent">
+2 -2
View File
@@ -256,10 +256,10 @@ class gitlab extends control
if(strpos($gitlab->url, 'http') !== 0) return $this->send(array('result' => 'fail', 'message' => array('url' => array(sprintf($this->lang->gitlab->hostError, $this->config->gitlab->minCompatibleVersion)))));
if(!$gitlab->token) return $this->send(array('result' => 'fail', 'message' => array('token' => array($this->lang->gitlab->tokenError))));
$user = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token, true);
$user = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token);
if(!is_object($user)) return $this->send(array('result' => 'fail', 'message' => array('url' => array(sprintf($this->lang->gitlab->hostError, $this->config->gitlab->minCompatibleVersion)))));
if(!isset($user->id)) return $this->send(array('result' => 'fail', 'message' => array('token' => array($this->lang->gitlab->tokenError))));
if(!isset($user->id) or !isset($user->is_admin) or !$user->is_admin) return $this->send(array('result' => 'fail', 'message' => array('token' => array($this->lang->gitlab->tokenError))));
/* Verify version compatibility. */
$result = $this->gitlab->getVersion($gitlab->url, $gitlab->token);
+1 -2
View File
@@ -473,10 +473,9 @@ class gitlabModel extends model
* @access public
* @return array
*/
public function apiGetCurrentUser($host, $token, $rootCheck = false)
public function apiGetCurrentUser($host, $token)
{
$host = rtrim($host, '/') . "/api/v4%s?private_token=$token";
if($rootCheck) $host .= '&sudo=1';
return $this->apiGet($host, '/user');
}
+2
View File
@@ -317,7 +317,9 @@ class group extends control
$this->view->title = $title;
$this->view->position = $position;
$this->view->allUsers = array('' => '') + $groupUsers + $this->loadModel('dept')->getDeptUserPairs($deptID);
$this->view->groupID = $groupID;
$this->view->deptID = $deptID;
$this->view->deptName = $deptID ? $this->dao->findById($deptID)->from(TABLE_DEPT)->fetch('name') : '';
$this->view->programs = $programs;
$this->view->projects = $projects;
$this->view->products = $products;
+1
View File
@@ -0,0 +1 @@
#sidebar .cell {margin-top: 40px;}
+4
View File
@@ -32,11 +32,15 @@ function addItem(obj)
var id = $(this).attr('id');
$(this).attr('name', name.replace(/\d+/g, maxNum));
$(this).attr('id', id.replace(/\d+/g, maxNum));
$(this).attr('checked', false);
})
$(lastTr).after($newRow);
$newRow.find('div.picker').remove();
$newRow.find('.picker-select').val('').picker({chosenMode: true});
var $picker = $newRow.find('.picker-select').data('zui.picker');
$picker.setDisabled(false);
setTimeout(function()
{
$newRow.removeClass('highlight');
+6
View File
@@ -20,13 +20,18 @@ $lang->group->managePriv = 'Mehrfachzuordnung';
$lang->group->managePrivByGroup = 'Rechte';
$lang->group->managePrivByModule = 'Modul Rechte';
$lang->group->byModuleTips = '<span class="tips">(SHIFT/STRG für Multi-Select)</span>';
$lang->group->allTips = 'After checking this option, the administrator can manage all objects in the system, including objects created later.';
$lang->group->manageMember = 'Mitglieder';
$lang->group->manageProjectAdmin = 'Manage Program Admins';
$lang->group->confirmDelete = 'Möchten Sie die Gruppe löschen?';
$lang->group->successSaved = 'Gespeichert!';
$lang->group->errorNotSaved = 'Fehlgeschlagen. Bitte aktion und Gruppe wählen.';
$lang->group->viewList = 'Anzeige ist zulässig.';
$lang->group->object = 'Manage Object';
$lang->group->manageProgram = 'Manage Program';
$lang->group->manageProject = 'Manage Project';
$lang->group->manageExecution = 'Manage ' . $lang->execution->common;
$lang->group->manageProduct = 'Manage ' . $lang->productCommon;
$lang->group->programList = 'Access Program';
$lang->group->productList = 'Produkte sind zugänglich.';
$lang->group->projectList = 'Projekte sind zugänglich.';
@@ -39,6 +44,7 @@ $lang->group->noneExecution = "No {$lang->execution->common}";
$lang->group->project = 'Project';
$lang->group->group = 'Group';
$lang->group->more = 'More';
$lang->group->allCheck = 'All';
global $config;
if($config->systemMode == 'new') $lang->group->noneProject = 'No Project';
+6
View File
@@ -20,13 +20,18 @@ $lang->group->managePriv = 'Gérer Privilèges';
$lang->group->managePrivByGroup = 'Gérer Privilèges par Groupe';
$lang->group->managePrivByModule = 'Gérer Privilèges par Module';
$lang->group->byModuleTips = '<span class="tips">(Shift/Ctrl pour sélection multiple)</span>';
$lang->group->allTips = 'After checking this option, the administrator can manage all objects in the system, including objects created later.';
$lang->group->manageMember = 'Gérer Membres';
$lang->group->manageProjectAdmin = 'Manage Program Admins';
$lang->group->confirmDelete = "Voulez-vous supprimer ce groupe d'utilisateurs ?";
$lang->group->successSaved = 'Sauvé.';
$lang->group->errorNotSaved = 'Echec. Veuillez sélectionner actions et groupes.';
$lang->group->viewList = 'Accès Consultation';
$lang->group->object = 'Manage Object';
$lang->group->manageProgram = 'Manage Program';
$lang->group->manageProject = 'Manage Project';
$lang->group->manageExecution = 'Manage ' . $lang->execution->common;
$lang->group->manageProduct = 'Manage ' . $lang->productCommon;
$lang->group->programList = 'Accè Programs';
$lang->group->productList = 'Accès ' . $lang->productCommon . 's';
$lang->group->projectList = 'Accès ' . $lang->executionCommon . 's';
@@ -39,6 +44,7 @@ $lang->group->noneExecution = "No {$lang->execution->common}";
$lang->group->project = 'Project';
$lang->group->group = 'Group';
$lang->group->more = 'More';
$lang->group->allCheck = 'All';
global $config;
if($config->systemMode == 'new') $lang->group->noneProject = 'No Project';
@@ -13,6 +13,12 @@
<?php include '../../common/view/header.html.php';?>
<div id='mainContent' class='main-row fade in'>
<div class="side-col" id="sidebar">
<div id="sidebarHeader">
<div class="title">
<?php echo $deptName ? $deptName : $lang->dept->common;?>
<?php if($deptName) echo html::a(inlink('manageProjectadmin', "groupID=$groupID"), "<i class='icon icon-sm icon-close'></i>", '', "class='text-muted'");?>
</div>
</div>
<div class='cell'>
<div class='panel panel-sm'>
<div class='panel-heading nobr'><strong><?php echo $lang->dept->common;?></strong></div>
+8 -8
View File
@@ -45,26 +45,26 @@ $lang->install->howToUse = "How do you like to use ZenTao?";
$lang->install->guideVideo = 'https://dl.cnezsoft.com/vedio/zentaoconcepteng0716.mp4';
$lang->install->introductionContent = <<<EOT
<div>
<h4>Dear users, welcome to ZenTao project management system.</h4>
<p>ZenTao has two managment modes in version 15.0 and up. One is the classic management mode, providing two core features, Product and Project; the other is a new project management mode, with Program and Execution added. The following is an introduction to the new mode:</p>
<h4>Dear users,</h4>
<p>Welcome to ZenTao project management system. ZenTao has two managment modes in version 15.0 and up. One is the classic management mode, providing two core features, Product and Project; the other is a new project management mode, with Program and Execution added. The following is an introduction to the new mode:</p>
<div class='block-content'>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i><strong>Program</strong></p><p>Program is used to manage a group of products and projects, and the company executives or PMO can use it for strategic planning.</p></div>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i> <strong>Program</strong></p><p>Program is used to manage a group of products and projects, and the company executives or PMO can use it for strategic planning.</p></div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-product'></i><strong>Product</strong></p>
<p class='block-title'><i class='icon icon-product'></i> <strong>Product</strong></p>
<p>Product is used to subdivide the company's strategy into requirements that can be developed, and the product manager can use it to make release plans.<p>
</div>
<div class='block-details'>
<p class='block-title'><i class='icon icon-project'></i><strong>Project</strong></p>
<p class='block-title'><i class='icon icon-project'></i> <strong>Project</strong></p>
<p>Project is used to organize the manpower for development, track and manage the project process, and complete the project in a faster, better, and less costly way.</p>
</div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-run'></i><strong>Execution</strong></p>
<p class='block-title'><i class='icon icon-run'></i> <strong>Execution</strong></p>
<p>Execution is used to decompose, assign, and track tasks to ensure that project goals can be implemented by manpower.<p>
</div>
</div>
<div class='text-center introduction-link'>
<a href='https://dl.cnezsoft.com/zentao/zentaoconcept.pdf' target='_blank' class='btn btn-wide btn-info'><i class='icon icon-p-square'></i> Document of introduction</a>
<a href='javascript:showVideo()' class='btn btn-wide btn-info'><i class='icon icon-video-play'></i> Video of introduction</a>
<a href='https://dl.cnezsoft.com/zentao/zentaoconcept.pdf' target='_blank' class='btn btn-wide btn-info'><i class='icon icon-p-square'></i> Introduction Document</a>
<a href='javascript:showVideo()' class='btn btn-wide btn-info'><i class='icon icon-video-play'></i> Introduction Video</a>
</div>
</div>
EOT;
+8 -8
View File
@@ -45,26 +45,26 @@ $lang->install->howToUse = "How do you like to use ZenTao?";
$lang->install->guideVideo = 'https://dl.cnezsoft.com/vedio/zentaoconcepteng0716.mp4';
$lang->install->introductionContent = <<<EOT
<div>
<h4>Dear users, welcome to ZenTao project management system.</h4>
<p>ZenTao has two managment modes in version 15.0 and up. One is the classic management mode, providing two core features, Product and Project; the other is a new project management mode, with Program and Execution added. The following is an introduction to the new mode:</p>
<h4>Dear users,</h4>
<p>Welcome to ZenTao project management system. ZenTao has two managment modes in version 15.0 and up. One is the classic management mode, providing two core features, Product and Project; the other is a new project management mode, with Program and Execution added. The following is an introduction to the new mode:</p>
<div class='block-content'>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i><strong>Program</strong></p><p>Program is used to manage a group of products and projects, and the company executives or PMO can use it for strategic planning.</p></div>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i> <strong>Program</strong></p><p>Program is used to manage a group of products and projects, and the company executives or PMO can use it for strategic planning.</p></div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-product'></i><strong>Product</strong></p>
<p class='block-title'><i class='icon icon-product'></i> <strong>Product</strong></p>
<p>Product is used to subdivide the company's strategy into requirements that can be developed, and the product manager can use it to make release plans.<p>
</div>
<div class='block-details'>
<p class='block-title'><i class='icon icon-project'></i><strong>Project</strong></p>
<p class='block-title'><i class='icon icon-project'></i> <strong>Project</strong></p>
<p>Project is used to organize the manpower for development, track and manage the project process, and complete the project in a faster, better, and less costly way.</p>
</div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-run'></i><strong>Execution</strong></p>
<p class='block-title'><i class='icon icon-run'></i> <strong>Execution</strong></p>
<p>Execution is used to decompose, assign, and track tasks to ensure that project goals can be implemented by manpower.<p>
</div>
</div>
<div class='text-center introduction-link'>
<a href='https://dl.cnezsoft.com/zentao/zentaoconcept.pdf' target='_blank' class='btn btn-wide btn-info'><i class='icon icon-p-square'></i> Document of introduction</a>
<a href='javascript:showVideo()' class='btn btn-wide btn-info'><i class='icon icon-video-play'></i> Video of introduction</a>
<a href='https://dl.cnezsoft.com/zentao/zentaoconcept.pdf' target='_blank' class='btn btn-wide btn-info'><i class='icon icon-p-square'></i> Introduction Document</a>
<a href='javascript:showVideo()' class='btn btn-wide btn-info'><i class='icon icon-video-play'></i> Introduction Video</a>
</div>
</div>
EOT;
+8 -8
View File
@@ -45,26 +45,26 @@ $lang->install->howToUse = "How do you like to use ZenTao?";
$lang->install->guideVideo = 'https://dl.cnezsoft.com/vedio/zentaoconcepteng0716.mp4';
$lang->install->introductionContent = <<<EOT
<div>
<h4>Dear users, welcome to ZenTao project management system.</h4>
<p>ZenTao has two managment modes in version 15.0 and up. One is the classic management mode, providing two core features, Product and Project; the other is a new project management mode, with Program and Execution added. The following is an introduction to the new mode:</p>
<h4>Dear users,</h4>
<p>Welcome to ZenTao project management system. ZenTao has two managment modes in version 15.0 and up. One is the classic management mode, providing two core features, Product and Project; the other is a new project management mode, with Program and Execution added. The following is an introduction to the new mode:</p>
<div class='block-content'>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i><strong>Program</strong></p><p>Program is used to manage a group of products and projects, and the company executives or PMO can use it for strategic planning.</p></div>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i> <strong>Program</strong></p><p>Program is used to manage a group of products and projects, and the company executives or PMO can use it for strategic planning.</p></div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-product'></i><strong>Product</strong></p>
<p class='block-title'><i class='icon icon-product'></i> <strong>Product</strong></p>
<p>Product is used to subdivide the company's strategy into requirements that can be developed, and the product manager can use it to make release plans.<p>
</div>
<div class='block-details'>
<p class='block-title'><i class='icon icon-project'></i><strong>Project</strong></p>
<p class='block-title'><i class='icon icon-project'></i> <strong>Project</strong></p>
<p>Project is used to organize the manpower for development, track and manage the project process, and complete the project in a faster, better, and less costly way.</p>
</div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-run'></i><strong>Execution</strong></p>
<p class='block-title'><i class='icon icon-run'></i> <strong>Execution</strong></p>
<p>Execution is used to decompose, assign, and track tasks to ensure that project goals can be implemented by manpower.<p>
</div>
</div>
<div class='text-center introduction-link'>
<a href='https://dl.cnezsoft.com/zentao/zentaoconcept.pdf' target='_blank' class='btn btn-wide btn-info'><i class='icon icon-p-square'></i> Document of introduction</a>
<a href='javascript:showVideo()' class='btn btn-wide btn-info'><i class='icon icon-video-play'></i> Video of introduction</a>
<a href='https://dl.cnezsoft.com/zentao/zentaoconcept.pdf' target='_blank' class='btn btn-wide btn-info'><i class='icon icon-p-square'></i> Introduction Document</a>
<a href='javascript:showVideo()' class='btn btn-wide btn-info'><i class='icon icon-video-play'></i> Introduction Video</a>
</div>
</div>
EOT;
+4 -4
View File
@@ -48,17 +48,17 @@ $lang->install->introductionContent = <<<EOT
<h4>尊敬的用户您好,欢迎您使用禅道项目管理系统。</h4>
<p> 禅道自15系列开始提供了两种使用模式,一种是经典管理模式,功能较为精简,主要提供了产品和项目两个核心功能;另一种是全新项目集管理模式,增加了项目集和执行的概念。下面是全新项目集管理模式的介绍:</p>
<div class='block-content'>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i><strong>项目集</strong></p><p>项目集用来管理一组相关的产品和项目,公司高层或者PMO可以用来做战略规划。</p></div>
<div class='block-details'><p class='block-title'><i class='icon icon-program'></i> <strong>项目集</strong></p><p>项目集用来管理一组相关的产品和项目,公司高层或者PMO可以用来做战略规划。</p></div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-product'></i><strong>产品</strong></p>
<p class='block-title'><i class='icon icon-product'></i> <strong>产品</strong></p>
<p>产品用来将公司的战略细分为可以进行研发的需求,产品经理可以用来做产品的发布计划。<p>
</div>
<div class='block-details'>
<p class='block-title'><i class='icon icon-project'></i><strong>项目</strong></p>
<p class='block-title'><i class='icon icon-project'></i> <strong>项目</strong></p>
<p>项目用来组织相应的人力进行研发,做好项目过程的跟踪管理,多快好省地完成项目。</p>
</div>
<div class='block-details block-right'>
<p class='block-title'><i class='icon icon-run'></i><strong>执行</strong></p>
<p class='block-title'><i class='icon icon-run'></i> <strong>执行</strong></p>
<p>执行用来做任务的分解、指派和跟踪,保证项目目标可以落实到人来执行。<p>
</div>
</div>
+2 -2
View File
@@ -35,7 +35,7 @@
<th><?php echo $lang->kanbanspace->team;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, '', "class='form-control picker-select' multiple data-dropDirection='bottom'");?>
<?php echo html::select('team[]', $users, '', "class='form-control picker-select' multiple data-drop-direction='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists');?>
</div>
</td>
@@ -48,7 +48,7 @@
</tr>
<tr id="whitelistBox" class="<?php echo $type == 'private' ? '' : 'hidden';?>">
<th><?php echo $lang->whitelist;?></th>
<td><?php echo html::select('whitelist[]', $users, '', 'class="form-control picker-select" multiple');?></td>
<td colspan='2'><?php echo html::select('whitelist[]', $users, '', 'class="form-control picker-select" multiple data-drop-direction="top"');?></td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
+2 -2
View File
@@ -36,7 +36,7 @@
<th><?php echo $lang->kanbanspace->team;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, $team, "class='form-control picker-select' multiple data-dropDirection='bottom'");?>
<?php echo html::select('team[]', $users, $team, "class='form-control picker-select' multiple data-drop-direction='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists');?>
</div>
</td>
@@ -49,7 +49,7 @@
</tr>
<tr id="whitelistBox" class="<?php echo $space->type == 'private' ? '' : 'hidden';?>">
<th><?php echo $lang->whitelist;?></th>
<td><?php echo html::select('whitelist[]', $users, $space->whitelist, 'class="form-control picker-select" multiple');?></td>
<td colspan='2'><?php echo html::select('whitelist[]', $users, $space->whitelist, 'class="form-control picker-select" multiple data-drop-direction="top"');?></td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
@@ -16,6 +16,7 @@
#archivedCards .kanban-item {border: 1px solid #ddd; border-radius: 4px; padding: 5px;}
#archivedCards .kanban-item > .title {display: block; max-height: 38px; overflow: hidden; color: inherit; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;}
#archivedCards .kanban-item > .title:hover {color: #2272eb}
#archivedCards .kanban-item > .desc {color: #838a9d; overflow: hidden; white-space:nowrap; text-overflow:ellipsis; padding-top: 5px;}
#archivedCards .kanban-item > .info {margin-top: 5px; position: relative;}
#archivedCards .kanban-item > .info > .pri {height: 14px; border-width: 1px; font-size: 12px; line-height: 12px; min-width: 14px; padding: 0 1px;}
#archivedCards .kanban-item > .info > .time {margin-left: 10px; font-size: 12px}
@@ -97,6 +98,7 @@ js::set('systemMode', $this->config->systemMode);
$name = isset($card->title) ? $card->title : $card->name;
if(common::hasPriv($card->fromType, 'view')) echo html::a($this->createLink($card->fromType, 'view', "id=$card->fromID"), $name, '', "class='cardName' title='$name'");
if(!common::hasPriv($card->fromType, 'view')) echo "<div class='cardName' title='$name'>$name</div>";
if($card->fromType == 'productplan' or $card->fromType == 'build') echo "<div class='desc' title='$card->desc'>$card->desc</div>";
echo "<div class='info $card->fromType'>";
if(isset($lang->{$card->fromType}->statusList[$card->objectStatus])) echo "<span class='label label-$card->objectStatus'>" . $lang->{$card->fromType}->statusList[$card->objectStatus] . '</span>';
if(isset($card->date) and !helper::isZeroDate($card->date)) echo "<span class='time label label-light'>" . date("Y-m-d", strtotime($card->date)) . "</span>"
-1
View File
@@ -453,7 +453,6 @@ EOF;
$this->loadModel('execution');
$queryID = ($type == 'bySearch') ? (int)$param : 0;
/* Save session. */
if($type != 'bySearch') $this->session->set('myTaskType', $type);
if($this->app->viewType != 'json') $this->session->set('taskList', $this->app->getURI(true), 'execution');
+2 -1
View File
@@ -1,9 +1,10 @@
#projectTableList > tr.drop-not-allowed {opacity: 0.1 !important;}
#projectList .c-actions {overflow: visible;}
#projectTableList > tr:last-child .c-actions .dropdown-menu {top: auto; bottom: 100%; margin-bottom: -5px;}
#projectList .c-budget {width: 100px; padding-right: 20px;}
#projectTableList .c-budget {width: 100px; padding-right: 20px;}
.c-date {width: 80px;}
.c-budget {width: 80px;}
.label-warning, .label-info {width: 60px !important;}
.project-type-label.label-outline {width: 50px; min-width: 50px;}
.c-date {width: 120px;}
+1
View File
@@ -17,3 +17,4 @@ td.delayed {background: #e84e0f !important; color: white;}
.c-hours {width: 50px;}
.c-status, .c-date, .c-user-short {width: 70px;}
.c-project {width: 130px;}
#taskTable .c-user{width: 110px; padding-left: 29px;}
+4
View File
@@ -4,3 +4,7 @@
.btn-group a.btn-primary {border-right: 1px solid rgba(255,255,255,0.2);}
.btn-toolbar .space {min-height: 1px; margin: 0 -3px 0 10px;}
.iconCenter {top: -2px !important;}
#switchButton {background: #fff !important;}
.panel-actions {position: relative; padding: 0;}
.panel-actions .btn-icon {padding-left: 7px;}
+1 -1
View File
@@ -64,7 +64,7 @@
<td class='text-left'><?php echo $project->begin;?></td>
<td class='text-left'><?php echo $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end;?></td>
<?php $projectBudget = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?>
<td class='text-right'><?php echo $project->budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $lang->project->future;?></td>
<td class='text-right c-budget'><?php echo $project->budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $lang->project->future;?></td>
<td>
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : ''?>
<?php if(!empty($project->PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $project->PM), '', "data-toggle='modal' data-type='iframe' data-width='600'");?>
+6
View File
@@ -35,6 +35,12 @@
</div>
</div>
<div class="btn-toolbar pull-right">
<?php if($config->edition != 'open' and !empty($app->user) and common::hasPriv('todo', 'calendar')):?>
<div class="btn-group panel-actions">
<?php echo html::a(helper::createLink('todo', 'calendar'), "<i class='icon-cards-view'></i> &nbsp;", '', "class='btn btn-icon' title='{$lang->todo->calendar}' id='switchButton'");?>
<?php echo html::a(helper::createLink('my', 'todo', "type=all"), "<i class='icon-list'></i> &nbsp;", '', "class='btn btn-icon text-primary' title='{$lang->todo->list}' id='switchButton'");?>
</div>
<?php endif;?>
<?php if(common::hasPriv('todo', 'export')) echo html::a(helper::createLink('todo', 'export', "userID={$user->id}&orderBy=$orderBy", 'html', true), "<i class='icon-export muted'> </i> " . $lang->todo->export, '', "class='btn btn-link export' data-width='600px'");?>
<?php if(common::hasPriv('todo', 'create') or common::hasPriv('todo', 'batchCreate')):?>
<div class='btn-group dropdown'>
+12 -10
View File
@@ -137,26 +137,28 @@ class personnelModel extends model
}
$users = $this->loadModel('user')->getListByAccounts(array_keys($accountPairs), 'account');
foreach($users as $user) $user->role = zget($this->lang->user->roleList, $user->role, $user->role);
foreach($accountPairs as $account => $projects)
{
$user = zget($users, $account, '');
$personnelList[$account]['realname'] = $user ? $user->realname : $account;
$personnelList[$account]['account'] = $account;
$personnelList[$account]['role'] = $user ? $user->role : '';
$personnelList[$account]['projects'] = $projects;
$personnelList[$account]['executions'] = zget($executionPairs, $account, 0);
if(!empty($user) and !isset($personnelList[$user->role])) $personnelList[$user->role] = array();
$personnelList[$account] += $taskInvest[$account];
$personnelList[$account] += $bugAndStoryInvest[$account];
$personnelList[$user->role][$account]['realname'] = $user ? $user->realname : $account;
$personnelList[$user->role][$account]['account'] = $account;
$personnelList[$user->role][$account]['role'] = $user ? zget($this->lang->user->roleList, $user->role, $user->role) : '';
$personnelList[$user->role][$account]['projects'] = $projects;
$personnelList[$user->role][$account]['executions'] = zget($executionPairs, $account, 0);
$personnelList[$user->role][$account] += $taskInvest[$account];
$personnelList[$user->role][$account] += $bugAndStoryInvest[$account];
if($this->config->edition == 'max')
{
$personnelList[$account] += $issueInvest[$account];
$personnelList[$account] += $riskInvest[$account];
$personnelList[$user->role][$account] += $issueInvest[$account];
$personnelList[$user->role][$account] += $riskInvest[$account];
}
}
krsort($personnelList);
return $personnelList;
}
+5 -3
View File
@@ -21,8 +21,8 @@
<table class="table has-sort-head table-fixed table-bordered text-center">
<thead>
<tr>
<th rowspan='2' class="c-user"> <?php echo $lang->personnel->name;?></th>
<th rowspan='2' class="c-role"><?php echo $lang->personnel->role;?></th>
<th rowspan='2' class="c-user"> <?php echo $lang->personnel->name;?></th>
<th rowspan='2'><?php echo $lang->personnel->projects;?></th>
<th rowspan='2'><?php echo $lang->personnel->executions;?></th>
<th colspan="2"><?php echo $lang->personnel->workingHours;?></th>
@@ -58,10 +58,11 @@
</tr>
</thead>
<tbody class="sortable">
<?php foreach($investList as $personnel):?>
<?php foreach($investList as $role => $personnelList):?>
<?php foreach($personnelList as $personnel):?>
<tr>
<td title='<?php echo $personnel['realname'];?>'><?php echo $personnel['realname'];?></td>
<td title='<?php echo $personnel['role'];?>' style="overflow: hidden; white-space:nowrap; text-overflow: ellipsis;"><?php echo $personnel['role'];?></td>
<td title='<?php echo $personnel['realname'];?>'><?php echo $personnel['realname'];?></td>
<td><?php echo $personnel['projects'];?></td>
<td><?php echo $personnel['executions'];?></td>
<td><?php echo round($personnel['consumedTask'], 1);?></td>
@@ -86,6 +87,7 @@
<?php endif;?>
</tr>
<?php endforeach;?>
<?php endforeach;?>
</tbody>
</table>
</form>
+7 -2
View File
@@ -1163,7 +1163,7 @@ class product extends control
/* Init vars. */
$idList = explode(',', trim($this->post->products, ','));
$orderBy = $this->post->orderBy;
if(strpos($orderBy, 'order') === false) return false;
if(strpos($orderBy, 'program') === false) return false;
/* Remove programID. */
foreach($idList as $i => $id)
@@ -1172,7 +1172,12 @@ class product extends control
}
/* Update order. */
$products = $this->dao->select('id,`order`')->from(TABLE_PRODUCT)->where('id')->in($idList)->orderBy($orderBy)->fetchPairs('order', 'id');
$products = $this->dao->select('t1.`order`, t1.id')->from(TABLE_PRODUCT)->alias('t1')
->leftJoin(TABLE_PROGRAM)->alias('t2')->on('t1.program = t2.id')
->where('t1.id')->in($idList)
->orderBy('t2.order_asc, t1.line_desc, t1.order_asc')
->fetchPairs('order', 'id');
foreach($products as $order => $id)
{
$newID = array_shift($idList);
+3 -2
View File
@@ -28,6 +28,7 @@ class program extends control
*/
public function browse($status = 'all', $orderBy = 'order_asc', $recTotal = 0, $recPerPage = 10, $pageID = 1, $param = 0)
{
$this->lang->program->featureBar = array('all' => $this->lang->program->featureBar['all']);
if(common::hasPriv('program', 'create')) $this->lang->pageActions = html::a($this->createLink('program', 'create'), "<i class='icon icon-plus'></i> " . $this->lang->program->create, '', "class='btn btn-primary create-program-btn'");
$this->session->set('programList', $this->app->getURI(true), 'program');
@@ -449,7 +450,7 @@ class program extends control
* @access public
* @return void
*/
public function project($programID = 0, $browseType = 'all', $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 15, $pageID = 1)
public function project($programID = 0, $browseType = 'doing', $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 15, $pageID = 1)
{
$programID = $this->program->saveState($programID, $this->program->getPairs());
setCookie("lastProgram", $programID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
@@ -543,7 +544,7 @@ class program extends control
{
if($confirm == 'no')
{
return print(js::confirm($this->lang->program->unlinkStakeholder, $this->inlink('unlinkStakeholder', "stakeholderID=$stakeholderID&programID=$programID&confirm=yes")));
return print(js::confirm($this->lang->program->confirmUnlink, $this->inlink('unlinkStakeholder', "stakeholderID=$stakeholderID&programID=$programID&confirm=yes")));
}
else
{
+2
View File
@@ -1,2 +1,4 @@
#budget {border-right: 0px;}
#budgetUnit {border-left: 0px;}
#dateRange {vertical-align: top; padding-top: 13px;}
#endList {vertical-align: top; padding-top: 13px;}
+2
View File
@@ -1,2 +1,4 @@
#budget {border-right: 0px;}
#budgetUnit {border-left: 0px;}
#dateRange {vertical-align: top; padding-top: 13px;}
#endList {vertical-align: top; padding-top: 13px;}
+11 -6
View File
@@ -99,15 +99,15 @@ $lang->program->noProgram = 'No program.';
$lang->program->showClosed = 'Closed programs.';
$lang->program->tips = 'If a parent program is selected, the products under the parent program can be associated. If no program is selected for the project, a product with the same name as the project is created and associated with the project by default.';
$lang->program->confirmBatchUnlink = "Do you want to batch unlink these stakeholders?";
$lang->program->beginLetterParent = "Parent begin date: %s, begin date should be > = parent begin date.";
$lang->program->endGreaterParent = "Parent end date: %s, end date should be < = parent end date.";
$lang->program->beginGreateChild = "Child earliest begin: %s, parent begin date < = child earliest begin date.";
$lang->program->endLetterChild = "Child latest end: %s, parent end date > = child latest end date.";
$lang->program->beginLetterParent = 'The start date of the program "%s" should be ≥ the start date of the parent program "%s": %s.';
$lang->program->endGreaterParent = 'The finish date of the program "%s" should be ≤ the finish date of the parent program "%s": %s.';
$lang->program->beginGreateChild = 'The start date of the parent program "%s" should be ≤the minimum start time of the subprogram "%s": %s.';
$lang->program->endLetterChild = 'The finish time of the parent program "%s" should be ≥ the maximum finish time of the subprogram "%s": %s.';
$lang->program->closeErrorMessage = 'There are subprograms or projects that are not closed';
$lang->program->hasChildren = 'It has child programs or projects. You cannot delete it.';
$lang->program->hasProduct = 'It has products. You cannot delete it.';
$lang->program->confirmDelete = "Do you want to delete it?";
$lang->program->unlinkStakeholder = 'Unlink Stakeholder';
$lang->program->confirmUnlink = 'Do you want to remove the Stakeholder?';
$lang->program->readjustTime = 'Change the program begin&end date.';
$lang->program->accessDenied = 'You have no access to the program.';
$lang->program->beyondParentBudget = 'The remaining budget of the owned program has been exceeded.';
@@ -138,7 +138,12 @@ $lang->program->statusList['doing'] = 'Doing';
$lang->program->statusList['suspended'] = 'Suspended';
$lang->program->statusList['closed'] = 'Closed';
$lang->program->featureBar['all'] = 'All';
$lang->program->featureBar['all'] = 'All';
$lang->program->featureBar['undone'] = 'Unfinished';
$lang->program->featureBar['wait'] = 'Waiting';
$lang->program->featureBar['doing'] = 'Doing';
$lang->program->featureBar['suspended'] = 'Suspended';
$lang->program->featureBar['closed'] = 'Closed';
$lang->program->kanban = new stdclass();
$lang->program->kanban->common = 'Program Kanban';
+11 -6
View File
@@ -99,15 +99,15 @@ $lang->program->noProgram = 'No program.';
$lang->program->showClosed = 'Closed';
$lang->program->tips = 'If a parent program is selected, the products under the parent program can be associated. If no program is selected for the project, a product with the same name as the project is created and associated with the project by default.';
$lang->program->confirmBatchUnlink = "Do you want to batch unlink these stakeholders?";
$lang->program->beginLetterParent = "Parent begin date: %s, begin date should be > = parent begin date.";
$lang->program->endGreaterParent = "Parent end date: %s, end date should be < = parent end date.";
$lang->program->beginGreateChild = "Child earliest begin: %s, parent begin date < = child earliest begin date.";
$lang->program->endLetterChild = "Child latest end: %s, parent end date > = child latest end date.";
$lang->program->beginLetterParent = 'The start date of the program "%s" should be ≥ the start date of the parent program "%s": %s.';
$lang->program->endGreaterParent = 'The finish date of the program "%s" should be ≤ the finish date of the parent program "%s": %s.';
$lang->program->beginGreateChild = 'The start date of the parent program "%s" should be ≤the minimum start time of the subprogram "%s": %s.';
$lang->program->endLetterChild = 'The finish time of the parent program "%s" should be ≥ the maximum finish time of the subprogram "%s": %s.';
$lang->program->closeErrorMessage = 'There are subprograms or projects that are not closed';
$lang->program->hasChildren = 'The program has a child program or the project exists and can not be deleted.';
$lang->program->hasProduct = 'The program has products exist and can not be deleted.';
$lang->program->confirmDelete = 'Do you want to delete the \"%s\" Program?';
$lang->program->unlinkStakeholder = 'Do you want to remove the Stakeholder?';
$lang->program->confirmUnlink = 'Do you want to remove the Stakeholder?';
$lang->program->readjustTime = 'Change the program begin&end date.';
$lang->program->accessDenied = 'You have no access to the program.';
$lang->program->beyondParentBudget = 'The remaining budget of the owned program has been exceeded.';
@@ -138,7 +138,12 @@ $lang->program->statusList['doing'] = 'Doing';
$lang->program->statusList['suspended'] = 'Suspended';
$lang->program->statusList['closed'] = 'Closed';
$lang->program->featureBar['all'] = 'All';
$lang->program->featureBar['all'] = 'All';
$lang->program->featureBar['undone'] = 'Unfinished';
$lang->program->featureBar['wait'] = 'Waiting';
$lang->program->featureBar['doing'] = 'Doing';
$lang->program->featureBar['suspended'] = 'Suspended';
$lang->program->featureBar['closed'] = 'Closed';
$lang->program->kanban = new stdclass();
$lang->program->kanban->common = 'Program Kanban';
+11 -6
View File
@@ -99,15 +99,15 @@ $lang->program->noProgram = 'No program.';
$lang->program->showClosed = 'Closed programs.';
$lang->program->tips = 'If a parent program is selected, the products under the parent program can be associated. If no program is selected for the project, a product with the same name as the project is created and associated with the project by default.';
$lang->program->confirmBatchUnlink = "Do you want to batch unlink these stakeholders?";
$lang->program->beginLetterParent = "Parent begin date: %s, begin date should be > = parent begin date.";
$lang->program->endGreaterParent = "Parent end date: %s, end date should be < = parent end date.";
$lang->program->beginGreateChild = "Child earliest begin: %s, parent begin date < = child earliest begin date.";
$lang->program->endLetterChild = "Child latest end: %s, parent end date > = child latest end date.";
$lang->program->beginLetterParent = 'La date de début du programme "%s" doit être ≥ à la date de début du programme parent "%s" : %s.';
$lang->program->endGreaterParent = 'La date de fin du programme "%s" doit être ≤ à la date de fin du programme parent "%s" : %s.';
$lang->program->beginGreateChild = 'La date de début du programme parent "%s" doit être ≤ à la date de début minimum du sous-programme "%s" : %s.';
$lang->program->endLetterChild = 'Le temps de fin du programme parent "%s" doit être ≥ au temps de fin maximum du sous-programme "%s" : %s.';
$lang->program->closeErrorMessage = 'There are subprograms or projects that are not closed';
$lang->program->hasChildren = 'It has child programs or projects. You cannot delete it.';
$lang->program->hasProduct = 'It has products. You cannot delete it.';
$lang->program->confirmDelete = "Do you want to delete it?";
$lang->program->unlinkStakeholder = 'Unlink Stakeholder';
$lang->program->unlinkStakeholder = 'Voulez - vous retirer les intervenants?';
$lang->program->readjustTime = 'Change the program begin&end date.';
$lang->program->accessDenied = 'You have no access to the program.';
$lang->program->beyondParentBudget = 'The remaining budget of the owned program has been exceeded.';
@@ -138,7 +138,12 @@ $lang->program->statusList['doing'] = 'Doing';
$lang->program->statusList['suspended'] = 'Suspended';
$lang->program->statusList['closed'] = 'Closed';
$lang->program->featureBar['all'] = 'All';
$lang->program->featureBar['all'] = 'All';
$lang->program->featureBar['undone'] = 'Non Terminées';
$lang->program->featureBar['wait'] = 'En Attente';
$lang->program->featureBar['doing'] = 'En Cours';
$lang->program->featureBar['suspended'] = 'Suspendues';
$lang->program->featureBar['closed'] = 'Fermées';
$lang->program->kanban = new stdclass();
$lang->program->kanban->common = 'Program Kanban';
+11 -6
View File
@@ -99,15 +99,15 @@ $lang->program->noProgram = '暂时没有项目集';
$lang->program->showClosed = '显示已关闭';
$lang->program->tips = '选择了父项目集,则可关联该父项目集下的产品。如果项目未选择任何项目集,则系统会默认创建一个和该项目同名的产品并关联该项目。';
$lang->program->confirmBatchUnlink = "您确定要批量移除这些干系人吗?";
$lang->program->beginLetterParent = "父项目集的开始日期:%s,开始日期不能小于父项目集的开始日期";
$lang->program->endGreaterParent = "父项目集的完成日期:%s,完成日期不能大于父项目集的完成日期";
$lang->program->beginGreateChild = "子项目集的最小开始日期:%s,父项目集的开始日期不能大于子项目集的最小开始日期";
$lang->program->endLetterChild = "子项目的最大完成日期:%s,父项目的完成日期不能小于子项目的最大完成日期";
$lang->program->beginLetterParent = '项目集“%s”开始日期应大于等于父项目集“%s”的开始日期:%s。';
$lang->program->endGreaterParent = '项目集“%s”完成日期应小于等于父项目集“%s”的完成日期:%s。';
$lang->program->beginGreateChild = '父项目集“%s”的开始日期应小于等于子项目集“%s”的最小开始时间:%s。';
$lang->program->endLetterChild = '父项目集“%s”的完成时间应大于等于子项目集“%s”的最大完成时间:%s。';
$lang->program->closeErrorMessage = '存在子项目集或项目为未关闭状态';
$lang->program->hasChildren = '该项目集有子项目集或项目存在,不能删除。';
$lang->program->hasProduct = '该项目集有产品存在,不能删除。';
$lang->program->confirmDelete = '您确定要删除\“%s\”项目集吗?';
$lang->program->unlinkStakeholder = '您确定要移除干系人吗?';
$lang->program->confirmUnlink = '您确定要移除干系人吗?';
$lang->program->readjustTime = '重新调整项目集起止时间';
$lang->program->accessDenied = '你无权访问该项目集';
$lang->program->beyondParentBudget = '已超出所属项目集的剩余预算';
@@ -138,7 +138,12 @@ $lang->program->statusList['doing'] = '进行中';
$lang->program->statusList['suspended'] = '已挂起';
$lang->program->statusList['closed'] = '已关闭';
$lang->program->featureBar['all'] = '所有';
$lang->program->featureBar['all'] = '所有';
$lang->program->featureBar['undone'] = '未完成';
$lang->program->featureBar['wait'] = '未开始';
$lang->program->featureBar['doing'] = '进行中';
$lang->program->featureBar['suspended'] = '已挂起';
$lang->program->featureBar['closed'] = '已关闭';
$lang->program->kanban = new stdclass();
$lang->program->kanban->common = '项目集看板';
+10 -10
View File
@@ -709,13 +709,13 @@ class programModel extends model
if($parentProgram)
{
/* Child program begin cannot less than parent. */
if($program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin);
if(!empty($program->name) and $program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $program->name, $parentProgram->name, $parentProgram->begin);
/* When parent set end then child program end cannot greater than parent. */
if($parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(!empty($program->name) and$parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $program->name, $parentProgram->name, $parentProgram->end);
/* When parent set end then child program cannot set longTime. */
if(empty($program->end) and $this->post->delta == 999 and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(!empty($program->name) and empty($program->end) and $this->post->delta == 999 and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $program->name, $parentProgram->name, $parentProgram->end);
/* The budget of a child program cannot beyond the remaining budget of the parent program. */
$program->budgetUnit = $parentProgram->budgetUnit;
@@ -799,11 +799,11 @@ class programModel extends model
if($children > 0)
{
$minChildBegin = $this->dao->select('min(begin) as minBegin')->from(TABLE_PROGRAM)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->fetch('minBegin');
$maxChildEnd = $this->dao->select('max(end) as maxEnd')->from(TABLE_PROGRAM)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->andWhere('end')->ne('0000-00-00')->fetch('maxEnd');
$minChildBegin = $this->dao->select('name, min(begin) as minBegin')->from(TABLE_PROGRAM)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->fetch();
$maxChildEnd = $this->dao->select('name, max(end) as maxEnd')->from(TABLE_PROGRAM)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->andWhere('end')->ne('0000-00-00')->fetch();
if($minChildBegin and $program->begin > $minChildBegin) dao::$errors['begin'] = sprintf($this->lang->program->beginGreateChild, $minChildBegin);
if($maxChildEnd and $program->end < $maxChildEnd and $this->post->delta != 999) dao::$errors['end'] = sprintf($this->lang->program->endLetterChild, $maxChildEnd);
if($minChildBegin and $program->begin > $minChildBegin) dao::$errors['begin'] = sprintf($this->lang->program->beginGreateChild, $program->name, $minChildBegin->name, $minChildBegin->minBegin);
if($maxChildEnd and $program->end < $maxChildEnd and $this->post->delta != 999) dao::$errors['end'] = sprintf($this->lang->program->endLetterChild, $program->name, $maxChildEnd->name, $maxChildEnd->maxEnd);
if(dao::isError()) return false;
}
@@ -818,9 +818,9 @@ class programModel extends model
$parentProgram = $this->dao->select('*')->from(TABLE_PROGRAM)->where('id')->eq($program->parent)->fetch();
if($parentProgram)
{
if($program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin);
if($parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(empty($program->end) and $this->post->delta == 999 and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end);
if(!empty($program->name) and $program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $program->name, $parentProgram->name, $parentProgram->begin);
if(!empty($program->name) and $parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $program->name, $parentProgram->name, $parentProgram->end);
if(!empty($program->name) and empty($program->end) and $this->post->delta == 999 and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $program->name, $parentProgram->name, $parentProgram->end);
}
/* The budget of a child program cannot beyond the remaining budget of the parent program. */
+2 -2
View File
@@ -88,7 +88,7 @@
</td>
</tr>
<tr>
<th><?php echo $lang->project->dateRange;?></th>
<th id="dateRange"><?php echo $lang->project->dateRange;?></th>
<td>
<div class='input-group'>
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->begin . "' required");?>
@@ -96,7 +96,7 @@
<?php echo html::input('end', '', "class='form-control form-date' placeholder='" . $lang->project->end . "' required");?>
</div>
</td>
<td colspan='2'><?php echo html::radio('delta', $lang->program->endList , '', "onclick='computeEndDate(this.value)'");?></td>
<td id="endList" colspan='2'><?php echo html::radio('delta', $lang->program->endList, '', "onclick='computeEndDate(this.value)'");?></td>
</tr>
<tr class='hide'>
<th><?php echo $lang->project->status;?></th>
+2 -2
View File
@@ -69,7 +69,7 @@
</td>
</tr>
<tr>
<th><?php echo $lang->project->dateRange;?></th>
<th id="dateRange"><?php echo $lang->project->dateRange;?></th>
<td>
<div class='input-group'>
<?php echo html::input('begin', $program->begin, "class='form-control form-date' placeholder='" . $lang->project->begin . "' required");?>
@@ -81,7 +81,7 @@
</div>
</td>
<?php $endValue = $program->end == LONG_TIME ? 999 : (strtotime($program->end) - strtotime($program->begin)) / 3600 / 24 + 1;?>
<td colspan='2'><?php echo html::radio('delta', $lang->program->endList , $endValue, "onclick='computeEndDate(this.value)'");?></td>
<td id="endList" colspan='2'><?php echo html::radio('delta', $lang->program->endList , $endValue, "onclick='computeEndDate(this.value)'");?></td>
</tr>
<tr>
<th><?php echo $lang->project->realBegan;?></th>
+3 -4
View File
@@ -696,6 +696,7 @@ class project extends control
if($this->post->names)
{
$allChanges = $this->project->batchUpdate();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
if(!empty($allChanges))
{
@@ -707,7 +708,8 @@ class project extends control
$this->action->logHistory($actionID, $changes);
}
}
return print(js::locate($this->session->projectList, 'parent'));
$locateLink = $this->session->projectList;
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink));
}
if(!$this->post->projectIdList) return print(js::locate($this->session->projectList, 'parent'));
@@ -1023,7 +1025,6 @@ class project extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
$sort = common::appendOrder($orderBy);
$bugs = $this->bug->getProjectBugs($projectID, $productID, $build, $type, $param, $sort, '', $pager);
$users = $this->user->getPairs('noletter');
/* team member pairs. */
$memberPairs = array();
@@ -1073,7 +1074,6 @@ class project extends control
$this->view->buildID = $this->view->build ? $this->view->build->id : 0;
$this->view->pager = $pager;
$this->view->orderBy = $orderBy;
$this->view->users = $users;
$this->view->productID = $productID;
$this->view->project = $this->project->getById($projectID);
$this->view->branchID = empty($this->view->build->branch) ? $branchID : $this->view->build->branch;
@@ -1082,7 +1082,6 @@ class project extends control
$this->view->param = $param;
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID);
$this->view->users = $this->user->getPairs('noletter');
$this->view->memberPairs = $this->user->getPairs('noletter|noclosed');
$this->view->branchOption = $branchOption;
$this->view->branchTagOption = $branchTagOption;
$this->view->executions = $executions;
+2
View File
@@ -1,6 +1,8 @@
.popover-sm .popover-content {padding: 8px 10px; max-width: 228px;}
.c-future {width: 56px;}
#dateRange {vertical-align: top; padding-top: 13px;}
#endList {vertical-align: top; padding-top: 13px;}
#copyProjectModal {padding: 0;}
#copyProjectModal {padding: 0 2px;}
#copyProjectModal > div {position: relative;}
+2
View File
@@ -2,3 +2,5 @@
#budgetUnit {border-left: 0px;}
#plansBox .row {display: inline-table; width: 102%;}
#plansBox .col-sm-4 {float: none; display: inline-block;}
#dateRange {vertical-align: top; padding-top: 13px;}
#endList {vertical-align: top; padding-top: 13px;}
+4 -3
View File
@@ -241,8 +241,9 @@ $lang->project->modelList['waterfall'] = "CMMI";
$lang->project->modelList['kanban'] = "Kanban";
$lang->project->featureBar['all'] = 'All';
$lang->project->featureBar['doing'] = 'Doing';
$lang->project->featureBar['undone'] = 'Unfinished';
$lang->project->featureBar['wait'] = 'Waiting';
$lang->project->featureBar['doing'] = 'Doing';
$lang->project->featureBar['suspended'] = 'Suspended';
$lang->project->featureBar['closed'] = 'Closed';
@@ -317,8 +318,8 @@ $lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s";
$lang->project->parentBudget = "The budget of the parent project: ";
$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project.";
$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project.";
$lang->project->beginGreateChild = "The minimum start date of the project set: %s. The start date of the project cannot be less than the minimum start date of the project set.";
$lang->project->endLetterChild = "The maximum finish date for the project set: %s. The completion date of a project cannot be greater than the maximum completion date of the project set.";
$lang->project->beginGreateChild = 'The start date of the project "%s" should be ≥ the start date of program "%s": %s.';
$lang->project->endLetterChild = 'The finish date of the project "%s" should be ≤ the finish date of program "%s": %s.';
$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too.";
$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+4 -3
View File
@@ -241,8 +241,9 @@ $lang->project->modelList['waterfall'] = "CMMI";
$lang->project->modelList['kanban'] = "Kanban";
$lang->project->featureBar['all'] = 'All';
$lang->project->featureBar['doing'] = 'Doing';
$lang->project->featureBar['undone'] = 'Unfinished';
$lang->project->featureBar['wait'] = 'Waiting';
$lang->project->featureBar['doing'] = 'Doing';
$lang->project->featureBar['suspended'] = 'Suspended';
$lang->project->featureBar['closed'] = 'Closed';
@@ -317,8 +318,8 @@ $lang->project->parentBeginEnd = "The begin and end date of the parent proj
$lang->project->parentBudget = "The budget of the parent project: ";
$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project.";
$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project.";
$lang->project->beginGreateChild = "The minimum start date of the project set: %s. The start date of the project cannot be less than the minimum start date of the project set.";
$lang->project->endLetterChild = "The maximum finish date for the project set: %s. The completion date of a project cannot be greater than the maximum completion date of the project set.";
$lang->project->beginGreateChild = 'The start date of the project "%s" should be ≥ the start date of program "%s": %s.';
$lang->project->endLetterChild = 'The finish date of the project "%s" should be ≤ the finish date of program "%s": %s.';
$lang->project->childLongTime = "There are long-term projects in the child project, and the parent project should also be a long-term project.";
$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+7 -6
View File
@@ -241,10 +241,11 @@ $lang->project->modelList['waterfall'] = "CMMI";
$lang->project->modelList['kanban'] = "Kanban";
$lang->project->featureBar['all'] = 'All';
$lang->project->featureBar['doing'] = 'Doing';
$lang->project->featureBar['wait'] = 'Waiting';
$lang->project->featureBar['suspended'] = 'Suspended';
$lang->project->featureBar['closed'] = 'Closed';
$lang->project->featureBar['undone'] = 'Non Terminées';
$lang->project->featureBar['wait'] = 'En Attente';
$lang->project->featureBar['doing'] = 'En Cours';
$lang->project->featureBar['suspended'] = 'Suspendues';
$lang->project->featureBar['closed'] = 'Fermées';
$lang->project->aclList['private'] = 'Private (For team members and stakeholders only)';
$lang->project->aclList['open'] = "Open (accessible with project view permissions)";
@@ -317,8 +318,8 @@ $lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s";
$lang->project->parentBudget = "The budget of the parent project: ";
$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project.";
$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project.";
$lang->project->beginGreateChild = "The minimum start date of the project set: %s. The start date of the project cannot be less than the minimum start date of the project set.";
$lang->project->endLetterChild = "The maximum finish date for the project set: %s. The completion date of a project cannot be greater than the maximum completion date of the project set.";
$lang->project->beginGreateChild = 'La date de début du projets "%s" doit être ≥ à la date de début du programme "%s" : %s.';
$lang->project->endLetterChild = 'La date de fin du projets "%s" doit être ≤ à la date de fin du programme "%s" : %s.';
$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too.";
$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?";
+4 -3
View File
@@ -241,8 +241,9 @@ $lang->project->modelList['waterfall'] = "瀑布";
$lang->project->modelList['kanban'] = "看板";
$lang->project->featureBar['all'] = '所有';
$lang->project->featureBar['doing'] = '进行中';
$lang->project->featureBar['undone'] = '未完成';
$lang->project->featureBar['wait'] = '未开始';
$lang->project->featureBar['doing'] = '进行中';
$lang->project->featureBar['suspended'] = '已挂起';
$lang->project->featureBar['closed'] = '已关闭';
@@ -317,8 +318,8 @@ $lang->project->parentBeginEnd = "父项目起止时间:%s ~ %s";
$lang->project->parentBudget = "父项目预算:";
$lang->project->beginLetterParent = "父项目的开始日期:%s,开始日期不能小于父项目的开始日期";
$lang->project->endGreaterParent = "父项目的完成日期:%s,完成日期不能大于父项目的完成日期";
$lang->project->beginGreateChild = "项目集的最小开始日期:%s,项目的开始日期不能小于项目集的最小开始日期";
$lang->project->endLetterChild = "项目集的最大完成日期:%s,项目的完成日期不能大于项目集的最大完成日期";
$lang->project->beginGreateChild = '项目“%s”的开始日期应大于等于项目集“%s”的最小开始日期:%s';
$lang->project->endLetterChild = '项目“%s”的完成日期应小于等于项目集“%s”的最大完成日期:%s';
$lang->project->childLongTime = "子项目中有长期项目,父项目也应该是长期项目";
$lang->project->confirmUnlinkMember = "您确定从该项目中移除该用户吗?";
+35 -8
View File
@@ -1085,10 +1085,10 @@ class projectModel extends model
if($program)
{
/* Child project begin cannot less than parent. */
if($project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $program->begin);
if(!empty($project->name) and $project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $project->name, $program->name, $program->begin);
/* When parent set end then child project end cannot greater than parent. */
if($program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $program->end);
if(!empty($project->name) and $$program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $project->name, $program->name, $program->end);
if(dao::isError()) return false;
}
@@ -1349,10 +1349,10 @@ class projectModel extends model
if($program)
{
/* Child project begin cannot less than parent. */
if($project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $program->begin);
if(!empty($project->name) and $project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $project->name, $program->name, $program->begin);
/* When parent set end then child project end cannot greater than parent. */
if($program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $program->end);
if(!empty($project->name) and $program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $project->name, $program->name, $program->end);
if(dao::isError()) return false;
}
@@ -1518,11 +1518,18 @@ class projectModel extends model
if($parentProject)
{
/* Child project begin cannot less than parent. */
if($projects[$projectID]->begin < $parentProject->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $parentProject->begin);
if(!empty($projects[$projectID]->name) and $projects[$projectID]->begin < $parentProject->begin)
{
dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $projects[$projectID]->name, $parentProject->name, $parentProject->begin);
return false;
}
/* When parent set end then child project end cannot greater than parent. */
if($parentProject->end != '0000-00-00' and $projects[$projectID]->end > $parentProject->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $parentProject->end);
if(!empty($projects[$projectID]->name) and $parentProject->end != '0000-00-00' and $projects[$projectID]->end > $parentProject->end)
{
dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $projects[$projectID]->name, $parentProject->name, $parentProject->end);
return false;
}
}
}
@@ -1534,7 +1541,7 @@ class projectModel extends model
$projects[$projectID]->{$extendField->field} = htmlSpecialString($projects[$projectID]->{$extendField->field});
}
}
if(dao::isError()) return print(js::error(dao::getError()));
if(dao::isError()) return false;
foreach($projects as $projectID => $project)
{
@@ -2225,6 +2232,26 @@ class projectModel extends model
return array('' => '') + $members;
}
/**
* Get team member group.
*
* @param array|string $projectIdList
* @access public
* @return array
*/
public function getTeamMemberGroup($projectIdList)
{
if(empty($projectIdList)) return array();
return $this->dao->select("t1.account, if(t2.deleted='0', t2.realname, t1.account) as realname, t1.root as project")->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account = t2.account')
->where('t1.root')->in($projectIdList)
->andWhere('t1.type')->eq('project')
->andWhere('t2.deleted')->eq('0')
->beginIF($this->config->vision)->andWhere("CONCAT(',', t2.visions, ',')")->like("%,{$this->config->vision},%")->fi()
->fetchGroup('project', 'account');
}
/**
* Get members of a project who can be imported.
*
+1 -1
View File
@@ -19,7 +19,7 @@
<div class="main-header">
<h2><?php echo $lang->project->batchEdit;?></h2>
</div>
<form method='post' class='load-indicator main-form' enctype='multipart/form-data' target='hiddenwin' id="batchEditForm">
<form method='post' class='load-indicator main-form form-ajax' enctype='multipart/form-data' id="batchEditForm">
<table class="table table-form">
<thead>
<tr>
+2 -2
View File
@@ -84,7 +84,7 @@
</td>
</tr>
<tr>
<th><?php echo $lang->project->dateRange;?></th>
<th id="dateRange"><?php echo $lang->project->dateRange;?></th>
<td>
<div class='input-group'>
<?php echo html::input('begin', date('Y-m-d'), "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->begin . "' required");?>
@@ -92,7 +92,7 @@
<?php echo html::input('end', '', "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->end . "' required");?>
</div>
</td>
<td colspan='2'><?php echo html::radio('delta', $lang->project->endList , '', "onclick='computeEndDate(this.value)'");?></td>
<td id="endList" colspan='2'><?php echo html::radio('delta', $lang->project->endList , '', "onclick='computeEndDate(this.value)'");?></td>
</tr>
<tr id='daysBox'>
<th><?php echo $lang->execution->days;?></th>
+2 -2
View File
@@ -89,7 +89,7 @@
</td>
</tr>
<tr>
<th><?php echo $lang->project->dateRange;?></th>
<th id="dateRange"><?php echo $lang->project->dateRange;?></th>
<td>
<div class='input-group'>
<?php echo html::input('begin', $project->begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->project->begin . "' required");?>
@@ -101,7 +101,7 @@
</div>
</td>
<?php $deltaValue = $project->end == LONG_TIME ? 999 : (strtotime($project->end) - strtotime($project->begin)) / 3600 / 24 + 1;?>
<td colspan='2'><?php echo html::radio('delta', $lang->project->endList , $deltaValue, "onclick='computeEndDate(this.value)'");?></td>
<td id="endList" colspan='2'><?php echo html::radio('delta', $lang->project->endList , $deltaValue, "onclick='computeEndDate(this.value)'");?></td>
</tr>
<tr id='daysBox' <?php if($project->end == LONG_TIME) echo "class='hidden'";?>>
<th><?php echo $lang->project->days;?></th>
+2 -2
View File
@@ -130,7 +130,7 @@ class projectrelease extends control
$this->view->projectID = $projectID;
$this->view->builds = $builds;
$this->view->lastRelease = $this->projectrelease->getLast($projectID);
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->confirmLink = $this->lang->release->confirmLink;
$this->display();
}
@@ -192,7 +192,7 @@ class projectrelease extends control
$this->view->release = $release;
$this->view->build = $build;
$this->view->builds = $builds;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->display();
}
+1 -1
View File
@@ -1 +1 @@
.checkbox-primary {display: inline-block; margin-left: 10px;}
#markerBox {display: inline-block; margin-left: 10px;}
+1 -1
View File
@@ -1,4 +1,4 @@
.table-form > tbody > tr > td > .row > [class*="col-"] .panel-heading {line-height: 16px;}
.contentDiv {height: 190px; overflow-y: auto; margin-bottom: 10px !important;}
.contentDiv .panel-heading {line-height: 14px;}
.checkbox-primary {display: inline-block; margin-left: 10px;}
#markerBox {display: inline-block; margin-left: 10px;}
+1 -1
View File
@@ -26,7 +26,7 @@
<th><?php echo $lang->release->name;?></th>
<td><?php echo html::input('name', '', "class='form-control' required");?></td>
<td class='muted'>
<div class='checkbox-primary'>
<div id='markerBox' class='checkbox-primary'>
<input id='marker' name='marker' value='1' type='checkbox' />
<label for='marker'><?php echo $lang->release->marker;?></label>
</div>
+1 -1
View File
@@ -29,7 +29,7 @@
<td><?php echo html::input('name', $release->name, "class='form-control' required");?></td>
<td>
<?php $checked = !empty($release->marker) ? "checked='checked'" : '';?>
<div class='checkbox-primary'>
<div id='markerBox' class='checkbox-primary'>
<input id='marker' name='marker' value='1' type='checkbox' <?php echo $checked;?> />
<label for='marker'><?php echo $lang->release->marker;?></label>
</div>
+2 -2
View File
@@ -99,7 +99,7 @@ class release extends control
$this->view->position[] = $this->lang->release->create;
$this->view->productID = $productID;
$this->view->builds = $builds;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->lastRelease = $this->release->getLast($productID, $branch);
$this->view->notEmptyBuilds = $notEmptyBuilds;
@@ -155,7 +155,7 @@ class release extends control
$this->view->release = $release;
$this->view->build = $build;
$this->view->builds = $builds;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->display();
}
+1 -1
View File
@@ -1 +1 @@
.checkbox-primary {display: inline-block; margin-left: 10px;}
#markerBox {display: inline-block; margin-left: 10px;}
+1 -1
View File
@@ -1,4 +1,4 @@
.table-form > tbody > tr > td > .row > [class*="col-"] .panel-heading {line-height: 16px;}
.contentDiv {height: 190px; overflow-y: auto; margin-bottom: 10px !important;}
.contentDiv .panel-heading {line-height: 14px;}
.checkbox-primary {display: inline-block; margin-left: 10px;}
#markerBox {display: inline-block; margin-left: 10px;}
+1 -1
View File
@@ -26,7 +26,7 @@
<th><?php echo $lang->release->name;?></th>
<td><?php echo html::input('name', '', "class='form-control' required");?></td>
<td class='muted'>
<div class='checkbox-primary'>
<div id='markerBox' class='checkbox-primary'>
<input id='marker' name='marker' value='1' type='checkbox' />
<label for='marker'><?php echo $lang->release->marker;?></label>
</div>
+1 -1
View File
@@ -29,7 +29,7 @@
<td><?php echo html::input('name', $release->name, "class='form-control' required");?></td>
<td>
<?php $checked = !empty($release->marker) ? "checked='checked'" : '';?>
<div class='checkbox-primary'>
<div id='markerBox' class='checkbox-primary'>
<input id='marker' name='marker' value='1' type='checkbox' <?php echo $checked;?> />
<label for='marker'><?php echo $lang->release->marker;?></label>
</div>
+20
View File
@@ -419,3 +419,23 @@ $lang->story->categoryList['safe'] = 'Safe';
$lang->story->categoryList['experience'] = 'Experience';
$lang->story->categoryList['improve'] = 'Improve';
$lang->story->categoryList['other'] = 'Other';
$lang->story->changeTip = 'This Story is under review and cannot be changed.';
$lang->story->reviewTip = array();
$lang->story->reviewTip['active'] = 'The Story is already active,no review requirements.';
$lang->story->reviewTip['notReviewer'] = 'You are not the reviewer of this Story and cannot perform review operations.';
$lang->story->reviewTip['reviewed'] = 'Reviewed';
$lang->story->reviewTip['recalled'] = 'This Story has been withdrawn from review and cannot be reviewed.';
$lang->story->recallTip = array();
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
$lang->story->recallTip['recalled'] = 'This Story has been withdrawn from review and cannot be cancelled.';
$lang->story->recallTip['reviewed'] = 'The review process has been started and cannot be cancelled.';
$lang->story->recallTip['notOpenedBy'] = 'You are not the Story creator and cannot cancel the operation.';
$lang->story->subDivideTip = array();
$lang->story->subDivideTip['subStory'] = 'The Sub-stories cannot be subdivided.';
$lang->story->subDivideTip['planned'] = 'The Story has been planned and cannot be subdivided.';
$lang->story->subDivideTip['projected'] = 'The Story has been initiated and cannot be subdivided.';
$lang->story->subDivideTip['notActive'] = 'The Story is not active and cannot be subdivided.';
+20
View File
@@ -419,3 +419,23 @@ $lang->story->categoryList['safe'] = 'Safe';
$lang->story->categoryList['experience'] = 'Experience';
$lang->story->categoryList['improve'] = 'Improve';
$lang->story->categoryList['other'] = 'Other';
$lang->story->changeTip = 'This Story is under review and cannot be changed.';
$lang->story->reviewTip = array();
$lang->story->reviewTip['active'] = 'The Story is already active,no review requirements.';
$lang->story->reviewTip['notReviewer'] = 'You are not the reviewer of this Story and cannot perform review operations.';
$lang->story->reviewTip['reviewed'] = 'Reviewed';
$lang->story->reviewTip['recalled'] = 'This Story has been withdrawn from review and cannot be reviewed.';
$lang->story->recallTip = array();
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
$lang->story->recallTip['recalled'] = 'This Story has been withdrawn from review and cannot be cancelled.';
$lang->story->recallTip['reviewed'] = 'The review process has been started and cannot be cancelled.';
$lang->story->recallTip['notOpenedBy'] = 'You are not the Story creator and cannot cancel the operation.';
$lang->story->subDivideTip = array();
$lang->story->subDivideTip['subStory'] = 'The Sub-stories cannot be subdivided.';
$lang->story->subDivideTip['planned'] = 'The Story has been planned and cannot be subdivided.';
$lang->story->subDivideTip['projected'] = 'The Story has been initiated and cannot be subdivided.';
$lang->story->subDivideTip['notActive'] = 'The Story is not active and cannot be subdivided.';
+20
View File
@@ -419,3 +419,23 @@ $lang->story->categoryList['safe'] = 'Safe';
$lang->story->categoryList['experience'] = 'Experience';
$lang->story->categoryList['improve'] = 'Improve';
$lang->story->categoryList['other'] = 'Other';
$lang->story->changeTip = 'Cette Story est en cours de vérification et ne peut pas être modifiée.';
$lang->story->reviewTip = array();
$lang->story->reviewTip['active'] = "Cette Story est déjà active, il n'y a pas de demande de révision.";
$lang->story->reviewTip['notReviewer'] = "Vous n'êtes pas l'évaluateur de cette Story et ne pouvez pas effectuer d'opérations d'évaluation.";
$lang->story->reviewTip['reviewed'] = "Révisé";
$lang->story->reviewTip['recalled'] = "Cette Story a été retirée pour vérification, et l'opération de révision ne peut pas être effectuée.";
$lang->story->recallTip = array();
$lang->story->recallTip['actived'] = "Aucun processus de révision n'a été lancé pour cette Story, et il n'est pas nécessaire de révoquer l'opération.";
$lang->story->recallTip['recalled'] = "Cette Story a été retirée pour vérification, et l'opération ne peut pas être annulée.";
$lang->story->recallTip['reviewed'] = "Il est entré dans le processus de révision, et l'opération ne peut pas être annulée.";
$lang->story->recallTip['notOpenedBy'] = "Vous n'êtes pas l'initiateur de la révision et vous ne pouvez pas annuler l'opération.";
$lang->story->subDivideTip = array();
$lang->story->subDivideTip['subStory'] = 'Les sous-stories ne peuvent pas être décomposées.';
$lang->story->subDivideTip['planned'] = 'Cette Story est planifiée et ne peut être subdivisée.';
$lang->story->subDivideTip['projected'] = 'Cette Story a été créée et ne peut être subdivisée.';
$lang->story->subDivideTip['notActive'] = "Cette Story n'est pas active et ne peut être subdivisée.";
+45 -12
View File
@@ -20,17 +20,13 @@ $lang->story->affectedStories = "Affected {$lang->story->story}";
$lang->story->batchCreate = "Tạo hàng loạt";
$lang->story->change = "Thay đổi";
$lang->story->changeAction = "Thay đổi câu chuyện";
$lang->story->changed = "Đã đổi";
$lang->story->assignTo = 'Giao cho';
$lang->story->assignAction = 'Bàn giao câu chuyện';
$lang->story->review = 'Xét duyệt';
$lang->story->recall = 'Revoke';
$lang->story->reviewAction = 'Duyệt câu chuyện';
$lang->story->needReview = 'Duyệt nhu cầu';
$lang->story->batchReview = 'Duyệt hàng loạt';
$lang->story->edit = "Sửa câu chuyện";
$lang->story->editAB = "Sửa câu chuyện";
$lang->story->batchEdit = "Sửa hàng loạt";
$lang->story->subdivide = 'Phân rã';
$lang->story->link = 'Link';
@@ -38,15 +34,11 @@ $lang->story->unlink = 'Unlink';
$lang->story->track = 'Track';
$lang->story->trackAB = 'Track';
$lang->story->processStoryChange= 'Process Story Change';
$lang->story->subdivideAction = 'Phân rã câu chuyện';
$lang->story->splitRequirent = 'Phân rã';
$lang->story->close = 'Đóng';
$lang->story->closeAction = 'Đóng câu chuyện';
$lang->story->batchClose = 'Đóng hàng loạt';
$lang->story->activate = 'Kích hoạt';
$lang->story->activateAction = 'Kích hoạt câu chuyện';
$lang->story->delete = "Xóa";
$lang->story->deleteAction = "Xóa câu chuyện";
$lang->story->view = "Chi tiết câu chuyện";
$lang->story->setting = "Thiết lập";
$lang->story->tasks = "Nhiệm vụ liên kết";
@@ -61,11 +53,9 @@ $lang->story->caseCountAB = 'C';
$lang->story->linkStory = 'Liên kết câu chuyện';
$lang->story->unlinkStory = 'Hủy liên kết';
$lang->story->export = "Xuất dữ liệu";
$lang->story->exportAction = "Xuất câu chuyện";
$lang->story->zeroCase = "Câu chuyện không tình huống";
$lang->story->zeroTask = "Chỉ liệt kê câu chuyện không nhiệm vụ";
$lang->story->reportChart = "Báo cáo";
$lang->story->reportAction = "Báo cáo câu chuyện";
$lang->story->copyTitle = "Sao chép tiêu đề";
$lang->story->batchChangePlan = "Thay đổi kế hoạch hàng loạt";
$lang->story->batchChangeBranch = "Thay đổi chi nhánh hàng loạt";
@@ -76,6 +66,19 @@ $lang->story->viewAll = "Xem tất cả";
$lang->story->toTask = 'Convert to Task';
$lang->story->batchToTask = 'Batch Convert to Task';
$lang->story->convertRelations = 'Convert Relations';
$lang->story->undetermined = 'undetermined';
$lang->story->order = 'Order';
$lang->story->editAction = "Edit {$lang->SRCommon}";
$lang->story->changeAction = "Change {$lang->SRCommon}";
$lang->story->assignAction = "Assign {$lang->SRCommon}";
$lang->story->reviewAction = "Review {$lang->SRCommon}";
$lang->story->subdivideAction = "Subdivide {$lang->SRCommon}";
$lang->story->closeAction = "Close {$lang->SRCommon}";
$lang->story->activateAction = "Activate {$lang->SRCommon}";
$lang->story->deleteAction = "Delete {$lang->SRCommon}";
$lang->story->exportAction = "Export {$lang->SRCommon}";
$lang->story->reportAction = "Report";
$lang->story->skipStory = '%s is a parent story. It cannot be closed.';
$lang->story->closedStory = 'Story %s is closed and will not be closed.';
@@ -83,7 +86,6 @@ $lang->story->batchToTaskTips = "This action will create a task with the same na
$lang->story->successToTask = "Converted to task.";
$lang->story->storyRound = '%s time estimation';
$lang->story->common = 'Câu chuyện';
$lang->story->id = 'ID';
$lang->story->parent = 'Mẹ';
$lang->story->product = $lang->productCommon;
@@ -95,6 +97,7 @@ $lang->story->source = 'Từ';
$lang->story->sourceNote = 'Ghi chú';
$lang->story->fromBug = 'Từ Bug';
$lang->story->title = 'Tiêu đề';
$lang->story->type = "Story/Requirement";
$lang->story->category = 'Category';
$lang->story->color = 'Màu';
$lang->story->toBug = 'Tới Bug';
@@ -122,9 +125,13 @@ $lang->story->closedDate = 'Ngày đóng';
$lang->story->closedReason = 'Lý do';
$lang->story->rejectedReason = 'Lý do từ chối';
$lang->story->reviewedBy = 'Người duyệt';
$lang->story->reviewer = $lang->story->reviewedBy;
$lang->story->reviewers = 'Reviewers';
$lang->story->reviewedDate = 'Ngày duyệt';
$lang->story->activatedDate = 'Activated Date';
$lang->story->version = 'Phiên bản';
$lang->story->feedbackBy = 'From Name';
$lang->story->notifyEmail = 'From Email';
$lang->story->plan = 'Kế hoạch liên kết';
$lang->story->planAB = 'Kế hoạch';
$lang->story->comment = 'Nhận xét';
@@ -141,7 +148,6 @@ $lang->story->colorTag = 'Màu';
$lang->story->files = 'Files';
$lang->story->copy = "Copy";
$lang->story->total = "Tổng câu chuyện";
$lang->story->allStories = 'Tất cả câu chuyện';
$lang->story->draft = 'Nháp';
$lang->story->unclosed = 'Chưa đóng';
$lang->story->deleted = 'Đã xóa';
@@ -157,6 +163,7 @@ $lang->story->field = 'Synchronized fields';
$lang->story->completeRate = 'Completion Rate';
$lang->story->reviewed = 'Reviewed';
$lang->story->toBeReviewed = 'To Be Reviewed';
$lang->story->linkMR = 'Related MRs';
$lang->story->ditto = 'Như trên';
$lang->story->dittoNotice = 'Câu chuyện này chưa liên kết tới cùng sản phẩm bởi bởi vì nó là cuối cùng!';
@@ -244,6 +251,7 @@ $lang->story->legendChildStories = 'Câu chuyện con';
$lang->story->legendSpec = 'Mô tả';
$lang->story->legendVerify = 'Chấp thuận';
$lang->story->legendMisc = 'Khác';
$lang->story->legendInformation = 'Story Information';
$lang->story->lblChange = "Đã đổi";
$lang->story->lblReview = 'Xét duyệt';
@@ -260,6 +268,7 @@ $lang->story->specTemplate = "Theo <một số người dùng>, Tôi mu
$lang->story->needNotReview = 'Không có xét duyệt được yêu cầu';
$lang->story->successSaved = "Câu chuyện đã lưu lại!";
$lang->story->confirmDelete = "Bạn có muốn xóa câu chuyện này?";
$lang->story->confirmRecall = "Do you want to recall this story?";
$lang->story->errorEmptyChildStory = '『Câu chuyện đã phân rã』 không thể để trống.';
$lang->story->errorNotSubdivide = "Nếu tình trạng này là chưa kích hoạt, hoặc giai đoạn này chưa đợi, hoặc một câu chuyện con, nó không thể bị chia nhỏ.";
$lang->story->errorEmptyReviewedBy = "『ReviewedBy』 không thể để trống.";
@@ -273,6 +282,9 @@ $lang->story->moveChildrenTips = "Its Child {$lang->SRCommon} will be moved
$lang->story->changeTips = 'The story associated with the requirements to change, click "Cancel" ignore this change, click "Confirm" to change the story.';
$lang->story->estimateMustBeNumber = 'Estimate value must be number.';
$lang->story->estimateMustBePlus = 'Estimated value cannot be negative';
$lang->story->confirmChangeBranch = $lang->SRCommon . ' %s is linked to the plan of its linked branch. If the branch is edited, ' . $lang->SRCommon . ' will be removed from the plan of its linked branch. Do you want to continue edit ' . $lang->SRCommon . '?';
$lang->story->confirmChangePlan = $lang->SRCommon . ' %s is linked to the branch of its plan. If the branch is edited, ' . $lang->SRCommon . ' will be removed from the plan. Do you want to continue edit branch ?';
$lang->story->errorDuplicateStory = $lang->SRCommon . '%s not exist';
$lang->story->form = new stdclass();
$lang->story->form->area = 'Phạm vi';
@@ -292,6 +304,7 @@ $lang->story->action->linked2plan = array('main' => '$date, liên kế
$lang->story->action->unlinkedfromplan = array('main' => '$date, bị hủy bởi <strong>$actor</strong> từ kế hoạch <strong>$extra</strong>.');
$lang->story->action->linked2execution = array('main' => '$date, liên kết bởi <strong>$actor</strong> tới ' . $lang->executionCommon . ' <strong>$extra</strong>.');
$lang->story->action->unlinkedfromexecution = array('main' => '$date, bị hủy bởi <strong>$actor</strong> từ ' . $lang->executionCommon . ' <strong>$extra</strong>.');
$lang->story->action->linked2kanban = array('main' => '$date, linked by <strong>$actor</strong> to Kanban <strong>$extra</strong>.');
$lang->story->action->linked2project = array('main' => '$date, liên kết bởi <strong>$actor</strong> tớ project <strong>$extra</strong>.');
$lang->story->action->unlinkedfromproject = array('main' => '$date, bị hủy bởi <strong>$actor</strong> từ project <strong>$extra</strong>.');
$lang->story->action->linked2build = array('main' => '$date, liên kết bởi <strong>$actor</strong> tới Bản dựng <strong>$extra</strong>');
@@ -406,3 +419,23 @@ $lang->story->categoryList['safe'] = 'Safe';
$lang->story->categoryList['experience'] = 'Experience';
$lang->story->categoryList['improve'] = 'Improve';
$lang->story->categoryList['other'] = 'Other';
$lang->story->changeTip = 'This Story is under review and cannot be changed.';
$lang->story->reviewTip = array();
$lang->story->reviewTip['active'] = 'The Story is already active,no review requirements.';
$lang->story->reviewTip['notReviewer'] = 'You are not the reviewer of this Story and cannot perform review operations.';
$lang->story->reviewTip['reviewed'] = 'Reviewed';
$lang->story->reviewTip['recalled'] = 'This Story has been withdrawn from review and cannot be reviewed.';
$lang->story->recallTip = array();
$lang->story->recallTip['actived'] = 'The Story has not initiated a review process and no undo action is required.';
$lang->story->recallTip['recalled'] = 'This Story has been withdrawn from review and cannot be cancelled.';
$lang->story->recallTip['reviewed'] = 'The review process has been started and cannot be cancelled.';
$lang->story->recallTip['notOpenedBy'] = 'You are not the Story creator and cannot cancel the operation.';
$lang->story->subDivideTip = array();
$lang->story->subDivideTip['subStory'] = 'The Sub-stories cannot be subdivided.';
$lang->story->subDivideTip['planned'] = 'The Story has been planned and cannot be subdivided.';
$lang->story->subDivideTip['projected'] = 'The Story has been initiated and cannot be subdivided.';
$lang->story->subDivideTip['notActive'] = 'The Story is not active and cannot be subdivided.';
+20
View File
@@ -419,3 +419,23 @@ $lang->story->categoryList['safe'] = '安全';
$lang->story->categoryList['experience'] = '体验';
$lang->story->categoryList['improve'] = '改进';
$lang->story->categoryList['other'] = '其他';
$lang->story->changeTip = '该需求正在评审中,无法进行变更';
$lang->story->reviewTip = array();
$lang->story->reviewTip['active'] = '该需求已是激活状态,无需评审';
$lang->story->reviewTip['notReviewer'] = '您不是该需求的评审人员,无法进行评审操作';
$lang->story->reviewTip['reviewed'] = '您已评审';
$lang->story->reviewTip['recalled'] = '该需求已撤销评审,无法进行评审操作';
$lang->story->recallTip = array();
$lang->story->recallTip['actived'] = '该需求未发起评审流程,无需撤销操作';
$lang->story->recallTip['recalled'] = '该需求已经撤销评审,无法进行撤销操作';
$lang->story->recallTip['reviewed'] = '已进入评审流程,无法进行撤销操作';
$lang->story->recallTip['notOpenedBy'] = '您不是需求创建者,无法进行撤销操作';
$lang->story->subDivideTip = array();
$lang->story->subDivideTip['subStory'] = '子需求无法细分';
$lang->story->subDivideTip['planned'] = '该需求已计划,无法进行细分操作';
$lang->story->subDivideTip['projected'] = '该需求已立项,无法进行细分操作';
$lang->story->subDivideTip['notActive'] = '需求不是激活状态,无法进行细分操作';
+61 -7
View File
@@ -3843,16 +3843,71 @@ class storyModel extends model
{
if(common::canBeChanged('story', $story))
{
$storyReviewer = isset($story->reviewer) ? $story->reviewer : array();
if($story->URChanged) return $this->buildMenu('story', 'processStoryChange', $params, $story, $type, 'search', '', 'iframe', true, '', $this->lang->confirm);
$menu .= $this->buildMenu('story', 'change', $params . "&from=$story->from", $story, $type, 'alter');
$menu .= $this->buildMenu('story', 'review', $params . "&from=$story->from", $story, $type, 'search');
$menu .= $this->buildMenu('story', 'recall', $params, $story, $type, 'undo', 'hiddenwin', '', '', '', $this->lang->story->recall);
$isClick = $this->isClickable($story, 'change');
$title = $isClick ? '' : $this->lang->story->changeTip;
$menu .= $this->buildMenu('story', 'change', $params . "&from=$story->from", $story, $type, 'alter', '', '', false, '', $title);
$isClick = $this->isClickable($story, 'review');
$title = $this->lang->story->review;
if(!$isClick)
{
if($story->status == 'active')
{
$title = $this->lang->story->reviewTip['active'];
}
elseif($storyReviewer and in_array($this->app->user->account, $storyReviewer))
{
$title = $this->lang->story->reviewTip['reviewed'];
}
elseif($storyReviewer and !in_array($this->app->user->account, $storyReviewer))
{
$title = $this->lang->story->reviewTip['notReviewer'];
}
elseif(empty($storyReviewer))
{
$title = $this->lang->story->reviewTip['recalled'];
}
}
$menu .= $this->buildMenu('story', 'review', $params . "&from=$story->from", $story, $type, 'search', '', '', false, '', $title);
$title = $this->lang->story->recall;
$isClick = $this->isClickable($story, 'recall');
if(!$isClick)
{
if($story->status == 'draft' and empty($storyReviewer)) $title = $this->lang->story->recallTip['recalled'];
if($story->status == 'draft' and !empty($storyReviewer)) $title = $this->lang->story->recallTip['reviewed'];
if(empty($story->reviewedBy) and strpos('draft,changed', $story->status) !== false and !empty($story->reviewer) and $this->app->user->account != $story->openedBy) $title = $this->lang->story->recallTip['notOpenedBy'];
if($story->status == 'active' and empty($story->reviewer)) $title = $this->lang->story->recallTip['actived'];
}
$menu .= $this->buildMenu('story', 'recall', $params, $story, $type, 'undo', 'hiddenwin', '', '', '', $title);
$menu .= $this->buildMenu('story', 'close', $params, $story, $type, '', '', 'iframe', true);
$menu .= $this->buildMenu('story', 'edit', $params . "&from=$story->from", $story, $type);
if($story->type != 'requirement' and $this->config->vision != 'lite') $menu .= $this->buildMenu('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=&param=0&$params", $story, $type, 'sitemap', '', '', false, "data-app='qa'");
if($this->app->rawModule != 'projectstory' OR $this->config->vision == 'lite') $menu .= $this->buildMenu('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&$params&executionID={$this->session->project}", $story, $type, 'split', '', '', '', '', $this->lang->story->subdivide);
if($this->app->rawModule != 'projectstory' OR $this->config->vision == 'lite')
{
$isClick = $this->isClickable($story, 'batchcreate');
$title = $this->lang->story->subdivide;
if(!$isClick)
{
if($story->parent > 0)
{
$title = $this->lang->story->subDivideTip['subStory'];
}
else
{
if($story->status != 'active') $title = $this->lang->story->subDivideTip['notActive'];
if(!empty($story->plan)) $title = $this->lang->story->subDivideTip['planned'];
if($story->stage == 'projected') $title = $this->lang->story->subDivideTip['projected'];
}
}
$menu .= $this->buildMenu('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&$params&executionID={$this->session->project}", $story, $type, 'split', '', '', '', '', $title);
}
if($this->app->rawModule == 'projectstory' and $this->config->vision != 'lite') $menu .= $this->buildMenu('projectstory', 'unlinkStory', "projectID={$this->session->project}&$params", $story, $type, 'unlink', 'hiddenwin');
}
else
@@ -3960,7 +4015,7 @@ class storyModel extends model
if($canBeChanged and common::hasPriv('execution', 'storyEstimate', $execution))
{
$menu .= common::printIcon('execution', 'storyEstimate', "executionID=$executionID&storyID=$story->id", '', 'list', 'estimate', '', 'iframe', true, "data-width='600px'");
$menu .= common::printIcon('execution', 'storyEstimate', "executionID=$executionID&storyID=$story->id", '', 'list', 'estimate', '', 'iframe', true, "data-width='450px'");
}
if($canBeChanged and common::hasPriv('execution', 'unlinkStory', $execution))
@@ -5073,7 +5128,6 @@ class storyModel extends model
$storyLang->newStory = str_replace($SRCommon, $URCommon, $storyLang->newStory);
$storyLang->copy = str_replace($SRCommon, $URCommon, $storyLang->copy);
$storyLang->total = str_replace($SRCommon, $URCommon, $storyLang->total);
$storyLang->allStories = str_replace($SRCommon, $URCommon, $storyLang->allStories);
$storyLang->released = str_replace($SRCommon, $URCommon, $storyLang->released);
$storyLang->legendLifeTime = str_replace($SRCommon, $URCommon, $storyLang->legendLifeTime);
$storyLang->legendLinkStories = str_replace($SRCommon, $URCommon, $storyLang->legendLinkStories);
+1 -1
View File
@@ -551,7 +551,7 @@ class task extends control
$this->view->position[] = $this->lang->task->edit;
$this->view->stories = $this->story->getExecutionStoryPairs($this->view->execution->id, 0, 'all', '', 'full', 'active');
$this->view->tasks = $tasks;
$this->view->users = $this->loadModel('user')->getPairs('nodeleted', "{$this->view->task->openedBy},{$this->view->task->canceledBy},{$this->view->task->closedBy}");
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed', "{$this->view->task->openedBy},{$this->view->task->canceledBy},{$this->view->task->closedBy}");
$this->view->showAllModule = isset($this->config->execution->task->allModule) ? $this->config->execution->task->allModule : '';
$this->view->modules = $this->tree->getTaskOptionMenu($this->view->task->execution, 0, 0, $this->view->showAllModule ? 'allModule' : '');
$this->view->executions = $this->config->systemMode == 'classic' ? $this->execution->getPairs() : $this->execution->getByProject($task->project, 'all', 0, true);
+2
View File
@@ -0,0 +1,2 @@
#mailtoGroup .chosen-container-single a {border-left-width: 0px;}
#ownerAndPriBox .picker .picker-selections .picker-selection {width: 158px;}
+3
View File
@@ -334,6 +334,9 @@ $config->delete['17_0_beta1'][] = 'extension/max/group/ext/model/flow.php';
$config->delete['17_0_beta1'][] = 'extension/max/user/ext/model/bizext.php';
$config->delete['17_0_beta1'][] = 'extension/max/sso/ext/model/bizext.php';
$config->delete['17_2'][] = 'extension/biz/my/ext/view/todo.calendar.html.hook.php';
$config->delete['17_2'][] = 'extension/max/my/ext/view/todo.calendar.html.hook.php';
$config->upgrade->openModules = array('action', 'admin', 'api', 'automation', 'backup', 'block', 'branch', 'budget', 'bug', 'build', 'caselib', 'ci', 'client', 'common', 'company', 'compile', 'convert', 'cron', 'custom', 'datatable', 'dept', 'design', 'dev', 'doc', 'durationestimation', 'entry', 'execution', 'extension', 'file', 'git', 'gitlab', 'group', 'holiday', 'im', 'index', 'index.html', 'install', 'issue', 'jenkins', 'job', 'kanban', 'license', 'mail', 'message', 'misc', 'mr', 'my', 'personnel', 'pipeline', 'product', 'productplan', 'productset', 'program', 'programplan', 'project', 'projectbuild', 'projectrelease', 'projectstory', 'qa', 'release', 'repo', 'report', 'risk', 'score', 'search', 'setting', 'sonarqube', 'sso', 'stage', 'stakeholder', 'story', 'subject', 'svn', 'task', 'testcase', 'testreport', 'testsuite', 'testtask', 'todo', 'tree', 'tutorial', 'upgrade', 'user', 'webhook', 'weekly', 'workestimation');
$config->upgrade->unsetModules = array('design', 'program', 'programplan', 'projectbuild', 'projectrelease', 'stage', 'stakeholder', 'product', 'branch', 'productplan', 'release', 'build', 'qa', 'bug', 'testcase', 'testtask', 'testreport', 'testsuite', 'caselib', 'automation', 'repo', 'ci', 'compile', 'jenkins', 'job', 'svn', 'gitlab', 'sonarqube', 'mr', 'git', 'report', 'sqlbuilder', 'feedback', 'faq', 'attend', 'holiday', 'leave', 'makeup', 'overtime', 'lieu', 'ops', 'host', 'serverroom', 'account', 'domain', 'service', 'deploy', 'conference', 'traincourse', 'pssp', 'baseline', 'classify', 'cm', 'cmcl', 'auditcl', 'reviewcl', 'process', 'activity', 'zoutput', 'auditplan', 'nc', 'subject', 'weekly', 'workestimation', 'issue', 'durationestimation', 'risk', 'opportunity', 'trainplan', 'gapanalysis', 'researchplan', 'researchreport', 'meeting', 'meetingroom', 'budget', 'reviewissue', 'reviewsetting', 'review', 'milestone', 'measurement', 'measrecord', 'assetlib', 'setting', 'im', 'client', 'ldap', 'dev', 'api');
+6 -3
View File
@@ -87,6 +87,8 @@ $lang->webhook->paramsList['comment'] = 'Kommentar';
$lang->webhook->paramsList['text'] = 'Aktionsbeschreibung';
$lang->webhook->confirmDelete = 'Möchten Sie diesen Hook löschen?';
$lang->webhook->friendlyTips = 'Friendly reminder: Click on a department to expand the sub-departments under the department.';
$lang->webhook->loadPrompt = 'There is a lot of data and the loading is slow, please wait.';
$lang->webhook->trimWords = '';
@@ -104,6 +106,7 @@ $lang->webhook->note->typeList['dingding'] = 'Fügen Sie einen eigenen bot in d
$lang->webhook->note->typeList['weixin'] = 'Add a customized bot in WeChat and get the webhook url.';
$lang->webhook->note->typeList['default'] = 'Webhookadresse on anderen erhalten.';
$lang->webhook->error = new stdclass();
$lang->webhook->error->curl = 'Laden Sie php-curl in der php.ini.';
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
$lang->webhook->error = new stdclass();
$lang->webhook->error->curl = 'Laden Sie php-curl in der php.ini.';
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
$lang->webhook->error->requestError = 'Request error!';
+6 -3
View File
@@ -87,6 +87,8 @@ $lang->webhook->paramsList['comment'] = 'Commentaire';
$lang->webhook->paramsList['text'] = "Description de l'Action";
$lang->webhook->confirmDelete = 'Voulez-vous vraiment supprimer ce flux ?';
$lang->webhook->friendlyTips = 'Friendly reminder: Click on a department to expand the sub-departments under the department.';
$lang->webhook->loadPrompt = 'There is a lot of data and the loading is slow, please wait.';
$lang->webhook->trimWords = '';
@@ -104,6 +106,7 @@ $lang->webhook->note->typeList['dingding'] = "Ajout d'un bot personnalis
$lang->webhook->note->typeList['weixin'] = "Ajoutez un bot personnalisé dans WeChat et obtenez l'url du webhook.";
$lang->webhook->note->typeList['default'] = "Obtenir les url d'autres flux webhook.";
$lang->webhook->error = new stdclass();
$lang->webhook->error->curl = 'Chargez php-curl dans php.ini.';
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
$lang->webhook->error = new stdclass();
$lang->webhook->error->curl = 'Chargez php-curl dans php.ini.';
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
$lang->webhook->error->requestError = 'Request error!';
+2 -2
View File
@@ -51,7 +51,7 @@ $(function()
{
enable: true,
chkStyle: "checkbox",
chkboxType: {"Y" : "s", "N" : "s"}
chkboxType: {"Y" : "ps", "N" : "ps"}
},
data:
{
@@ -176,7 +176,7 @@ $(function()
{
enable: true,
chkStyle: "checkbox",
chkboxType: {"Y":"s", "N":"s"}
chkboxType: {"Y" : "ps", "N" : "ps"}
},
data:
{