Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/master_lanzongjun_fixbug

This commit is contained in:
lanzongjun
2022-06-17 15:29:36 +08:00
35 changed files with 291 additions and 200 deletions
@@ -2,9 +2,9 @@
helper::importControl('execution');
class myExecution extends execution
{
public function edit($executionID, $action = 'edit', $extra = '')
public function edit($executionID, $action = 'edit', $extra = '', $newPlans = '', $confirm = 'no')
{
$this->config->execution->edit->requiredFields = 'name,code,begin,end';
parent::edit($executionID, $action, $extra);
}
}
}
+1 -1
View File
@@ -103,7 +103,7 @@ class model extends baseModel
if($action->extensionType == 'override') return $this->loadModel('flow')->buildActionMenu($moduleName, $action, $data, $type);
$conditions = json_decode($action->conditions);
if($action->extensionType == 'extend')
if($conditions and $action->extensionType == 'extend')
{
if($icon != 'copy' and $methodName != 'create') $title = $action->name;
if($conditions) $enabled = $this->loadModel('flow')->checkConditions($conditions, $data);
+2 -4
View File
@@ -692,7 +692,7 @@ class actionModel extends model
* @param string $orderBy
* @param object $pager
* @access public
* @return void
* @return array
*/
public function getTrashesBySearch($objectType, $type, $queryID, $orderBy, $pager = null)
{
@@ -716,9 +716,7 @@ class actionModel extends model
$extra = $type == 'hidden' ? self::BE_HIDDEN : self::CAN_UNDELETED;
$trashQuery = $this->session->trashQuery;
$trashQuery = preg_replace("/`objectID`/", 't1.`objectID`', $trashQuery);
$trashQuery = preg_replace("/`actor`/", 't1.`actor`', $trashQuery);
$trashQuery = preg_replace("/`date`/", 't1.`date`', $trashQuery);
$trashQuery = str_replace(array('`objectID`', '`actor`', '`date`'), array('t1.`objectID`', 't1.`actor`', 't1.`date`'), $trashQuery);
$table = $this->config->objectTables[$objectType];
$nameField = isset($this->config->action->objectNameFields[$objectType]) ? 't2.' . "`{$this->config->action->objectNameFields[$objectType]}`" : '';
+1
View File
@@ -0,0 +1 @@
#mainMenu .btn-toolbar a.btn {padding: 6px 3px;}
+1
View File
@@ -4,3 +4,4 @@
.side-col .cell {padding: 0px;}
.tab-pane table {border: 1px solid #ddd; border-top: none;}
.btn-edit-comment {z-index: 100;}
.modal-body {right: 15px;}
+2 -2
View File
@@ -18,7 +18,7 @@ $('#tostory').click(function()
*/
function loadProductExecutions(productID, projectID)
{
link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID +'&branch=' + branchID + '&number=&executionID=0&from=bugToTask');
var link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID +'&branch=' + branchID + '&number=&executionID=0&from=bugToTask');
$('#executionBox').load(link, function()
{
@@ -41,7 +41,7 @@ $('#toTaskButton').on('click', function()
else if(systemMode == 'classic' && executionID)
{
$('#cancelButton').click();
link = createLink('task', 'create', 'executionID=' + executionID + '&storyID=0&moduleID=0&taskID=0&todoID=0&extra=projectID=0&bugID=' + bugID);
var link = createLink('task', 'create', 'executionID=' + executionID + '&storyID=0&moduleID=0&taskID=0&todoID=0&extra=projectID=0&bugID=' + bugID);
window.parent.$.apps.open(link, 'execution');
}
else if(executionID == 0)
+2 -1
View File
@@ -428,10 +428,11 @@ $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed;
$lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe;
$lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe;
$lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe;
$lang->bug->featureBar['browse']['assignedbyme'] = $lang->bug->assignedByMe;
$lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved;
$lang->bug->featureBar['browse']['more'] = $lang->more;
$lang->bug->moreSelects['assignedbyme'] = $lang->bug->assignedByMe;
$lang->bug->moreSelects['unconfirmed'] = $lang->bug->unconfirmed;
$lang->bug->moreSelects['assigntonull'] = $lang->bug->assignToNull;
$lang->bug->moreSelects['longlifebugs'] = $lang->bug->longLifeBugs;
+1
View File
@@ -432,6 +432,7 @@ $lang->bug->featureBar['browse']['assignedbyme'] = $lang->bug->assignedByMe;
$lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved;
$lang->bug->featureBar['browse']['more'] = $lang->more;
$lang->bug->moreSelects['unconfirmed'] = $lang->bug->unconfirmed;
$lang->bug->moreSelects['assigntonull'] = $lang->bug->assignToNull;
$lang->bug->moreSelects['longlifebugs'] = $lang->bug->longLifeBugs;
+1 -4
View File
@@ -1619,10 +1619,7 @@ class bugModel extends model
if($moduleName == 'contributeBug')
{
$bugsAssignedByMe = $this->loadModel('my')->getAssignedByMe($account, 0, $pager, $orderBy, 0, 'bug');
foreach($bugsAssignedByMe as $bugID => $bug)
{
$bugIDList[$bugID] = $bugID;
}
foreach($bugsAssignedByMe as $bugID => $bug) $bugIDList[$bugID] = $bugID;
}
if($queryID)
+6 -6
View File
@@ -46,23 +46,23 @@ class commonModel extends model
public function syncPPEStatus($objectID)
{
global $app;
$thisModule = $app->rawModule;
$rawModule = $app->rawModule;
if($this->config->systemMode == 'classic')
{
if($thisModule == 'task') $this->syncExecutionStatus($objectID);
if($rawModule == 'task') $this->syncExecutionStatus($objectID);
}
if($this->config->systemMode == 'new')
{
if($thisModule == 'task' or $thisModule == 'effort')
if($rawModule == 'task' or $rawModule == 'effort')
{
$taskID = $objectID;
$execution = $this->syncExecutionStatus($taskID);
$project = $this->syncProjectStatus($execution);
$this->syncProgramStatus($project);
}
if($thisModule == 'execution')
if($rawModule == 'execution')
{
$executionID = $objectID;
$execution = $this->dao->select('id, project, grade, parent')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch();
@@ -70,13 +70,13 @@ class commonModel extends model
$project = $this->syncProjectStatus($execution);
$this->syncProgramStatus($project);
}
if($thisModule == 'project')
if($rawModule == 'project')
{
$projectID = $objectID;
$project = $this->dao->select('id, parent, path')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch();
$this->syncProgramStatus($project);
}
if($thisModule == 'program')
if($rawModule == 'program')
{
$programID = $objectID;
$program = $this->dao->select('id, parent, path')->from(TABLE_PROGRAM)->where('id')->eq($programID)->fetch();
-3
View File
@@ -7,9 +7,6 @@
<style>
.histories-list > li {word-break: break-word; word-wrap: break-word;}
.history-changes del {padding-left: 3px;}
#actionbox {margin: unset;}
#actionbox .detail-title {padding-left: 10px;}
#actionbox > .detail-content {padding-left: 10px; width:100%; max-height: 800px; overflow: scroll;}
</style>
<script>
$(function()
+9 -6
View File
@@ -362,6 +362,7 @@ class doc extends control
$this->view->objectType = $objectType;
$this->view->objectID = $objectID;
$this->view->libID = $libID;
$this->view->lib = $lib;
$this->view->libs = $libs;
$this->view->gobackLink = $gobackLink;
$this->view->libName = $this->dao->findByID($libID)->from(TABLE_DOCLIB)->fetch('name');
@@ -832,19 +833,21 @@ class doc extends control
* @param int $doclibID
* @param string $acl open|custom|private
* @param string $control user|group
* @param int $docID
* @access public
* @return string
*/
public function ajaxGetWhitelist($doclibID, $acl = '', $control = '')
public function ajaxGetWhitelist($doclibID, $acl = '', $control = '', $docID = 0)
{
$doclib = $this->doc->getLibById($doclibID);
$users = $this->user->getPairs('noletter|noempty|noclosed');
$selectedUser = $doclib->users;
$doclib = $this->doc->getLibById($doclibID);
$doc = $this->doc->getById($docID);
$users = $this->user->getPairs('noletter|noempty|noclosed');
$selectedUser = $docID ? $doc->users : $doclib->users;
$selectedGroup = $docID ? $doc->groups : $doclib->groups;
if($control == 'group')
{
$groups = $this->loadModel('group')->getPairs();
$selectedGroup = $doclib->groups;
$groups = $this->loadModel('group')->getPairs();
if($doclib->acl == 'custom')
{
foreach($groups as $groupID => $group)
+5 -54
View File
@@ -32,7 +32,11 @@ function toggleAcl(acl, type)
{
$('#whiteListBox').removeClass('hidden');
$('#groupBox').addClass('hidden');
if(type == 'doc') loadWhitelist(libID);
if(type == 'doc')
{
loadWhitelist(libID);
$('#whiteListBox').addClass('hidden');
}
}
else
{
@@ -85,59 +89,6 @@ function loadDocModule(libID)
loadWhitelist(libID);
}
/**
* Load whitelist by libID.
*
* @param int $libID
* @access public
* @return void
*/
function loadWhitelist(libID)
{
var groupLink = createLink('doc', 'ajaxGetWhitelist', 'libID=' + libID + '&acl=&control=group');
var userLink = createLink('doc', 'ajaxGetWhitelist', 'libID=' + libID + '&acl=&control=user');
$.post(groupLink, function(groups)
{
if(!(groups == 'default' || groups == 'private'))
{
$('#groups').replaceWith(groups);
$('#groups_chosen').remove();
$('#groups').chosen();
}
});
$.post(userLink, function(users)
{
if(users != 'default')
{
if(users == 'private')
{
$('#aclopen').parent('.radio-inline').addClass('hidden');
$('#aclcustom').parent('.radio-inline').addClass('hidden');
$('#aclprivate').prop('checked', true);
}
else
{
$('#aclopen').parent('.radio-inline').removeClass('hidden');
$('#aclcustom').parent('.radio-inline').removeClass('hidden');
$('#aclprivate').prop('checked', false);
$('#users').replaceWith(users);
$('#users_chosen').remove();
$('#whiteListBox .picker').remove();
if($('#users option').length < maxCount)
{
$('#users').chosen();
}
else
{
$('#users').picker();
}
}
}
});
}
/**
* Set cookie of browse type and reload.
*
+54 -1
View File
@@ -1,6 +1,6 @@
$(function()
{
toggleAcl($('[name=acl]').val(), 'doc');
toggleAcl($('input[name="acl"]:checked').val(), 'doc');
setTimeout(function(){initPage(docType)}, 50);
$('input[name="type"]').change(function()
{
@@ -101,3 +101,56 @@ function initPage(type)
$('#urlBox').hide();
}
}
/**
* Load whitelist by libID.
*
* @param int $libID
* @access public
* @return void
*/
function loadWhitelist(libID)
{
var groupLink = createLink('doc', 'ajaxGetWhitelist', 'libID=' + libID + '&acl=&control=group');
var userLink = createLink('doc', 'ajaxGetWhitelist', 'libID=' + libID + '&acl=&control=user');
$.post(groupLink, function(groups)
{
if(!(groups == 'default' || groups == 'private'))
{
$('#groups').replaceWith(groups);
$('#groups_chosen').remove();
$('#groups').chosen();
}
});
$.post(userLink, function(users)
{
if(users != 'default')
{
if(users == 'private')
{
$('#aclopen').parent('.radio-inline').addClass('hidden');
$('#aclcustom').parent('.radio-inline').addClass('hidden');
$('#whiteListBox').addClass('hidden');
$('#aclprivate').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();
if($('#users option').length < maxCount)
{
$('#users').chosen();
}
else
{
$('#users').picker();
}
}
}
});
}
+53
View File
@@ -125,3 +125,56 @@ function saveDraft()
var link = createLink('doc', 'ajaxSaveDraft', 'docID=' + docID);
$.post(link, {content: content});
}
/**
* Load whitelist by libID.
*
* @param int $libID
* @access public
* @return void
*/
function loadWhitelist(libID)
{
var groupLink = createLink('doc', 'ajaxGetWhitelist', 'libID=' + libID + '&acl=&control=group' + '&docID=' + docID);
var userLink = createLink('doc', 'ajaxGetWhitelist', 'libID=' + libID + '&acl=&control=user' + '&docID=' + docID);
$.post(groupLink, function(groups)
{
if(!(groups == 'default' || groups == 'private'))
{
$('#groups').replaceWith(groups);
$('#groups_chosen').remove();
$('#groups').chosen();
}
});
$.post(userLink, function(users)
{
if(users != 'default')
{
if(users == 'private')
{
$('#aclopen').parent('.radio-inline').addClass('hidden');
$('#aclcustom').parent('.radio-inline').addClass('hidden');
$('#whiteListBox').addClass('hidden');
$('#aclprivate').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();
if($('#users option').length < maxCount)
{
$('#users').chosen();
}
else
{
$('#users').picker();
}
}
}
});
}
+4 -4
View File
@@ -927,6 +927,7 @@ class docModel extends model
{
$this->config->doc->search['module'] = 'contributeDoc';
$products = $this->product->getPairs();
$this->config->doc->search['params']['project']['values'] = array('' => '') + $this->loadModel('project')->getPairsByProgram() + array('all' => $this->lang->doc->allProjects);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs() + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['lib']['values'] = array('' => '') + $this->loadModel('doc')->getLibs('all', 'withObject') + array('all' => $this->lang->doclib->all);
@@ -940,10 +941,9 @@ class docModel extends model
$this->config->doc->search['params']['lib']['values'] = array('' => '', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all);
}
$this->config->doc->search['actionURL'] = $actionURL;
$this->config->doc->search['queryID'] = $queryID;
$this->config->doc->search['params']['product']['values'] = array('' => '') + $products + array('all' => $this->lang->doc->allProduct);
$this->config->doc->search['actionURL'] = $actionURL;
$this->config->doc->search['queryID'] = $queryID;
$this->config->doc->search['params']['product']['values'] = array('' => '') + $products + array('all' => $this->lang->doc->allProduct);
/* Get the modules. */
$moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'doc', $startModuleID = 0);
+2 -2
View File
@@ -108,8 +108,8 @@ $("a[href^='###']").click(function()
<tr>
<th><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php echo html::radio('acl', $lang->doc->aclList, 'open', "onchange='toggleAcl(this.value, \"doc\")'");?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc']['open'];?></span>
<?php echo html::radio('acl', $lang->doc->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"doc\")'");?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$lib->acl];?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
+1
View File
@@ -34,3 +34,4 @@ td.flex span.project-type-label {min-width: 40px;}
canvas {height: 28px;}
.parent.has-child.c-name.flex, .table-child-bottom > .c-name.flex {border-bottom: 1px solid #cbd0db !important;}
.parent.has-child.c-name.flex {margin-bottom: -2px !important;}
#tableCustomBtn {padding-bottom: 5px;}
+3 -1
View File
@@ -14,7 +14,7 @@ $.zui.Picker.DEFAULTS.onChange = function(event)
var $select = $(this);
var selectPicker = $select.data('zui.picker');
if(selectPicker) selectPicker.updateOptionList([newItem]);
if(selectPicker) selectPicker.updateOptionList([$.extend({}, newItem)]);
});
}
@@ -104,6 +104,8 @@ function addItem(obj)
function deleteItem(obj)
{
if($('#teamForm .table tbody').children().length < 2) return false;
$(obj).closest('tr').find('.picker .picker-selection-remove').click();
$(obj).closest('tr').remove();
}
+14 -13
View File
@@ -707,12 +707,12 @@ class executionModel extends model
}
/* Update burn before close execution. */
$closedIDList = array();
$closedIdList = array();
foreach($executions as $executionID => $execution)
{
if(isset($execution->status) and in_array($execution->status, array('done', 'closed', 'suspended'))) $closedIDList[$executionID] = $executionID;
if(isset($execution->status) and in_array($execution->status, array('done', 'closed', 'suspended'))) $closedIdList[$executionID] = $executionID;
}
$this->computeBurn($closedIDList);
$this->computeBurn($closedIdList);
foreach($executions as $executionID => $execution)
{
@@ -2540,11 +2540,11 @@ class executionModel extends model
$this->loadModel('story');
if(!empty($plans))
{
foreach($plans as $planIDList)
foreach($plans as $planIdList)
{
if(empty($planIDList)) continue;
$planIDList = explode(',', $planIDList);
foreach($planIDList as $planID)
if(empty($planIdList)) continue;
$planIdList = explode(',', $planIdList);
foreach($planIdList as $planID)
{
$planStory = $this->story->getPlanStories($planID);
if(!empty($planStory))
@@ -3973,17 +3973,17 @@ class executionModel extends model
$this->loadModel('productplan');
$param = strtolower($param);
$branchIDList = strpos($param, 'withmainplan') !== false ? array(BRANCH_MAIN => BRANCH_MAIN) : array();
$branchIdList = strpos($param, 'withmainplan') !== false ? array(BRANCH_MAIN => BRANCH_MAIN) : array();
$branchGroups = $this->getBranchByProduct(array_keys($products), $executionID, 'noclosed');
foreach($branchGroups as $branches)
{
foreach($branches as $branchID => $branchName) $branchIDList[$branchID] = $branchID;
foreach($branches as $branchID => $branchName) $branchIdList[$branchID] = $branchID;
}
$plans = $this->dao->select('id,title,product,parent,begin,end')->from(TABLE_PRODUCTPLAN)
->where('product')->in(array_keys($products))
->andWhere('deleted')->eq(0)
->andWhere('branch')->in($branchIDList)->fi()
->andWhere('branch')->in($branchIdList)->fi()
->beginIF(strpos($param, 'skipparent') !== false)->andWhere('parent')->ne(-1)->fi()
->orderBy('begin desc')
->fetchAll('id');
@@ -4147,7 +4147,7 @@ class executionModel extends model
}
/**
* printCell
* Print cell data.
*
* @param object $col
* @param object $execution
@@ -4196,7 +4196,7 @@ class executionModel extends model
if($id == 'status')
{
$executionStatus = $this->processStatus('execution', $execution);
$title = " title='{$executionStatus}'";
$title = " title='{$executionStatus}'";
}
if(in_array($id, array('estimate', 'consumed', 'left')))
@@ -4205,7 +4205,8 @@ class executionModel extends model
$title .= $execution->hours->{$totalTitle} . $this->lang->execution->workHour;
}
echo "<td class='" . $class . "'" . $title . ">";
echo "<td class='{$class}' $title>";
if($this->config->edition != 'open') $this->loadModel('flow')->printFlowCell('execution', $execution, $id);
if($id == 'burn')
{
$burnValue = join(',', $execution->burns);
+11 -2
View File
@@ -149,6 +149,15 @@ js::set('errorEnd', $lang->execution->errorGreaterProject);
<script>
$('#executionForm').submit(function()
{
/* Clear all error messages. */
$('input[name^=begins]').each(function()
{
var beginDateID = $(this).attr('id');
var endDateID = beginDateID.replace('begins', 'ends');
$('#help' + beginDateID).remove();
$('#help' + endDateID).remove();
});
var submitForm = true;
$('input[name^=begins]').each(function()
{
@@ -161,7 +170,7 @@ $('#executionForm').submit(function()
$('#help' + beginDateID).remove();
$('#help' + endDateID).remove();
// Invalid data is skipped.
/* Invalid data is skipped. */
var nameVal = $('#' + nameID).val()
if(!nameVal) return;
@@ -184,7 +193,7 @@ $('#executionForm').submit(function()
}
});
// Check if the begin date is empty.
/* Check if the begin date is empty. */
if(!beginDate)
{
submitForm = false;
+3 -10
View File
@@ -185,19 +185,12 @@
<?php if($execution->projectInfo->grade > 1):?>
<i class='icon icon-program text-muted'></i>
<?php
$end = end($programList);
reset($programList);
$names = '';
foreach($programList as $id => $name)
{
if($name != $end)
{
echo common::hasPriv('program', 'product')? html::a($this->createLink('program', 'product', "programID=$id"), $name) . '/ ' : $name . '/ ';
}
else
{
echo common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) : $name;
}
$names .= common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) . '/ ' : $name . '/ ';
}
echo rtrim($names, '/ ');
?>
<?php endif;?>
</div>
+1 -1
View File
@@ -25,7 +25,7 @@ $lang->install->seeLatestRelease = 'View the latest version';
$lang->install->welcome = 'Thanks for choosing ZenTao!';
$lang->install->license = 'License';
$lang->install->desc = <<<EOT
ZenTao ALM is an open source software released under <a href='http://zpl.pub/page/zplv12.html' target='_blank'>Z Public License</a>. It integrates with Product Management, Project Management, Test Management, Document Management, CI Management, etc. ZenTao is a perfect choice for managing software development projects.
ZenTao ALM is an open source software released under <a href='http://zpl.pub/page/zplv12.html' target='_blank'>ZPL</a> or <a href='https://www.gnu.org/licenses/agpl-3.0.en.html' target='_blank'>AGPL</a> License. It integrates with Product Management, Project Management, Test Management, Document Management, CI Management, etc. ZenTao is a perfect choice for managing software development projects.
ZenTao ALM is built on PHP + MySQL + zentaoPHP which is an independent framework developed by EasyCorp. Third-party developers/organizations can develop extensions or customize ZenTao accordingly.
EOT;
+1 -1
View File
@@ -25,7 +25,7 @@ $lang->install->seeLatestRelease = '看看最新的版本';
$lang->install->welcome = '欢迎使用禅道项目管理软件!';
$lang->install->license = '禅道项目管理软件授权协议';
$lang->install->desc = <<<EOT
禅道项目管理软件(ZenTaoPMS)是一款国产的,基于<a href='http://zpl.pub' target='_blank'>ZPL</a>协议,开源免费的项目管理软件,它集产品管理、项目管理、测试管理于一体,同时还包含了事务管理、组织管理等诸多功能,是中小型企业项目管理的首选。
禅道项目管理软件(ZenTaoPMS)是一款国产的,基于<a href='http://zpl.pub/page/zplv12.html' target='_blank'>ZPL</a>或<a href='https://www.gnu.org/licenses/agpl-3.0.en.html' target='_blank'>AGPL</a>双授权协议,开源免费的项目管理软件,它集产品管理、项目管理、测试管理于一体,同时还包含了事务管理、组织管理等诸多功能,是中小型企业项目管理的首选。
禅道项目管理软件使用PHP + MySQL开发,基于自主的PHP开发框架──ZenTaoPHP而成。第三方开发者或者企业可以非常方便的开发插件或者进行定制。
EOT;
+1 -1
View File
@@ -38,7 +38,7 @@
.kanbans .kanban-members > span:after {right: -4px;}
.kanbans .kanban-members-total {display: inline-block; margin-left: 6px; position: relative; top: 3px}
.kanbans .kanbanAcl {position: absolute; right: 0px; bottom: 2px; color: #838a9d;}
.kanbans .kanban-label {margin: 8px 6px 0px 0px; padding: 2.5px 4px; float: left; color: #ff8a53; border: 0.8px solid #ff8a53;}
.kanbans .kanban-label {margin: 8px 6px 0px 0px; padding: 2.5px 4px; float: left; color: #ff8a53; border: 0.8px solid #ff8a53; background: none;}
@media screen and (max-width: 1366px){.kanbans .kanban-name {width: 66%;}}
a.disabled {pointer-events: none;}
+10 -8
View File
@@ -799,7 +799,7 @@ function moveCard(cardID, fromColID, toColID, fromLaneID, toLaneID, kanbanID, re
$('.kanban-group-header').hide();
$(".title").attr("disabled", true).css("pointer-events", "none");
}
setTooltip();
setToolTip();
},
error: function(xhr, status, error)
{
@@ -1228,10 +1228,7 @@ function createColumnMenu(options)
if(privs.includes('copyColumn')) items.push({label: kanbanLang.copyColumn, icon: 'copy', url: createLink('kanban', 'copyColumn', 'columnID=' + column.id), className: 'iframe', attrs: {'data-toggle': 'modal'}});
var otherActions = ((privs.includes('archiveColumn') && kanban.archived == '1') || privs.includes('deleteColumn')) ? true : false;
if(columnActions && otherActions)
{
items.push({type: 'divider'});
}
if(columnActions && otherActions) items.push({type: 'divider'});
if(privs.includes('archiveColumn') && kanban.archived == '1') items.push({label: kanbanLang.archiveColumn, icon: 'card-archive', url: createLink('kanban', 'archiveColumn', 'columnID=' + column.id), attrs: {'target': 'hiddenwin'}});
if(privs.includes('deleteColumn')) items.push({label: kanbanLang.deleteColumn, icon: 'trash', url: createLink('kanban', 'deleteColumn', 'columnID=' + column.id), attrs: {'target': 'hiddenwin'}});
@@ -1486,7 +1483,7 @@ $(function()
resetRegionHeight('open');
if(!CRKanban && kanbanInfo.status == 'closed') $('.kanban-col.kanban-header-col').css('padding', '0px 0px 0px 0px');
setTooltip();
setToolTip();
});
function initSortable()
@@ -1700,7 +1697,6 @@ function resetRegionHeight(fold)
{
$('.region').css('height', regionHeaderHeight);
}
}
$(document).on('click', '.dropdown-menu', function()
@@ -1708,7 +1704,13 @@ $(document).on('click', '.dropdown-menu', function()
$.zui.ContextMenu.hide();
});
function setTooltip()
/**
* Alerts for exceeding the limit.
*
* @access public
* @return void
*/
function setToolTip()
{
$('[data-toggle="tooltip"]').tooltip({container: 'body'});
}
+26 -25
View File
@@ -9,30 +9,31 @@
* @version $Id: en.php 5091 2013-07-10 06:06:46Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
$lang->product->index = $lang->productCommon . ' Home';
$lang->product->browse = 'Story List';
$lang->product->dynamic = 'Dynamics';
$lang->product->view = "{$lang->productCommon} Detail";
$lang->product->edit = "Edit {$lang->productCommon}";
$lang->product->batchEdit = 'Batch Edit';
$lang->product->create = "Create {$lang->productCommon}";
$lang->product->delete = "Delete {$lang->productCommon}";
$lang->product->deleted = 'Deleted';
$lang->product->close = "Close";
$lang->product->select = "Select {$lang->productCommon}";
$lang->product->mine = 'Mine';
$lang->product->other = 'Others';
$lang->product->closed = 'Closed';
$lang->product->closedProduct = 'Closed Product';
$lang->product->updateOrder = 'Order';
$lang->product->all = "{$lang->productCommon} List";
$lang->product->manageLine = "Manage {$lang->productCommon} Line";
$lang->product->newLine = "Create {$lang->productCommon} Line";
$lang->product->export = 'Export';
$lang->product->dashboard = "Dashboard";
$lang->product->changeProgram = "{$lang->productCommon} confirmation of the scope of influence of adjustment of the program set";
$lang->product->addWhitelist = 'Add Whitelist';
$lang->product->unbindWhitelist = 'Unbind Whitelist';
$lang->product->index = $lang->productCommon . ' Home';
$lang->product->browse = 'Story List';
$lang->product->dynamic = 'Dynamics';
$lang->product->view = "{$lang->productCommon} Detail";
$lang->product->edit = "Edit {$lang->productCommon}";
$lang->product->batchEdit = 'Batch Edit';
$lang->product->create = "Create {$lang->productCommon}";
$lang->product->delete = "Delete {$lang->productCommon}";
$lang->product->deleted = 'Deleted';
$lang->product->close = "Close";
$lang->product->select = "Select {$lang->productCommon}";
$lang->product->mine = 'Mine';
$lang->product->other = 'Others';
$lang->product->closed = 'Closed';
$lang->product->closedProduct = 'Closed Product';
$lang->product->updateOrder = 'Order';
$lang->product->all = "{$lang->productCommon} List";
$lang->product->manageLine = "Manage {$lang->productCommon} Line";
$lang->product->newLine = "Create {$lang->productCommon} Line";
$lang->product->export = 'Export';
$lang->product->dashboard = "Dashboard";
$lang->product->changeProgram = "{$lang->productCommon} confirmation of the scope of influence of adjustment of the program set";
$lang->product->changeProgramTip = "%s > Change Program";
$lang->product->addWhitelist = 'Add Whitelist';
$lang->product->unbindWhitelist = 'Unbind Whitelist';
$lang->product->indexAction = "All {$lang->productCommon}";
$lang->product->closeAction = "Close {$lang->productCommon}";
@@ -86,7 +87,7 @@ $lang->product->confirmDelete = " Do you want to delete the {$lang->produ
$lang->product->errorNoProduct = "No {$lang->productCommon} is created yet!";
$lang->product->accessDenied = "You have no access to the {$lang->productCommon}.";
$lang->product->programChangeTip = "The projects linked with this {$lang->productCommon}: %s will be transferred to the modified program set together.";
$lang->product->notChangeProgramTip = "The {$lang->SRCommon} of {$lang->productCommon} has been linked to the following projects, please cancel the link before proceeding";
$lang->product->notChangeProgramTip = "The {$lang->SRCommon} of {$lang->productCommon} has been linked to the following projects, please click the project name to enter the {$lang->SRCommon} list to cancel the link before proceeding";
$lang->product->confirmChangeProgram = "The projects linked with this {$lang->productCommon}: %s is also linked with other products, whether to transfer projects to the modified program set.";
$lang->product->changeProgramError = "The {$lang->SRCommon} of this {$lang->productCommon} has been linked to the project, please unlink it before proceeding";
$lang->product->changeLineError = "Products already exist under the product line, so the program within them cannot be modified.";
+26 -25
View File
@@ -9,30 +9,31 @@
* @version $Id: zh-cn.php 5091 2013-07-10 06:06:46Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
$lang->product->index = $lang->productCommon . '主页';
$lang->product->browse = "{$lang->SRCommon}列表";
$lang->product->dynamic = $lang->productCommon . '动态';
$lang->product->view = "{$lang->productCommon}概况";
$lang->product->edit = "编辑{$lang->productCommon}";
$lang->product->batchEdit = '批量编辑';
$lang->product->create = "添加{$lang->productCommon}";
$lang->product->delete = "删除{$lang->productCommon}";
$lang->product->deleted = '已删除';
$lang->product->close = '关闭';
$lang->product->select = "请选择{$lang->productCommon}";
$lang->product->mine = '我负责';
$lang->product->other = '其他';
$lang->product->closed = '已关闭';
$lang->product->closedProduct = '已关闭的产品';
$lang->product->updateOrder = '排序';
$lang->product->all = "所有{$lang->productCommon}";
$lang->product->manageLine = "维护{$lang->productCommon}线";
$lang->product->newLine = "新建{$lang->productCommon}线";
$lang->product->export = '导出数据';
$lang->product->dashboard = "{$lang->productCommon}仪表盘";
$lang->product->changeProgram = "{$lang->productCommon}调整所属项目集影响范围确认";
$lang->product->addWhitelist = '添加白名单';
$lang->product->unbindWhitelist = '移除白名单';
$lang->product->index = $lang->productCommon . '主页';
$lang->product->browse = "{$lang->SRCommon}列表";
$lang->product->dynamic = $lang->productCommon . '动态';
$lang->product->view = "{$lang->productCommon}概况";
$lang->product->edit = "编辑{$lang->productCommon}";
$lang->product->batchEdit = '批量编辑';
$lang->product->create = "添加{$lang->productCommon}";
$lang->product->delete = "删除{$lang->productCommon}";
$lang->product->deleted = '已删除';
$lang->product->close = '关闭';
$lang->product->select = "请选择{$lang->productCommon}";
$lang->product->mine = '我负责';
$lang->product->other = '其他';
$lang->product->closed = '已关闭';
$lang->product->closedProduct = '已关闭的产品';
$lang->product->updateOrder = '排序';
$lang->product->all = "所有{$lang->productCommon}";
$lang->product->manageLine = "维护{$lang->productCommon}线";
$lang->product->newLine = "新建{$lang->productCommon}线";
$lang->product->export = '导出数据';
$lang->product->dashboard = "{$lang->productCommon}仪表盘";
$lang->product->changeProgram = "{$lang->productCommon}调整所属项目集影响范围确认";
$lang->product->changeProgramTip = "%s > 修改项目集";
$lang->product->addWhitelist = '添加白名单';
$lang->product->unbindWhitelist = '移除白名单';
$lang->product->indexAction = "所有{$lang->productCommon}仪表盘";
$lang->product->closeAction = "关闭{$lang->productCommon}";
@@ -86,7 +87,7 @@ $lang->product->confirmDelete = " 您确定删除该{$lang->productCommon
$lang->product->errorNoProduct = "还没有创建{$lang->productCommon}";
$lang->product->accessDenied = "您无权访问该{$lang->productCommon}";
$lang->product->programChangeTip = "如下项目只关联了该{$lang->productCommon} 将直接转移至新项目集下。";
$lang->product->notChangeProgramTip = "{$lang->productCommon}{$lang->SRCommon}已经关联到如下项目,请取消关联后再操作";
$lang->product->notChangeProgramTip = "{$lang->productCommon}{$lang->SRCommon}已经关联到如下项目,请点击项目名称进入{$lang->SRCommon}列表取消关联后再操作";
$lang->product->confirmChangeProgram = "如下项目既关联了该{$lang->productCommon}又关联了其他{$lang->productCommon},请确认是否继续关联该{$lang->productCommon},勾选后将取消与其他{$lang->productCommon}的关联关系,同时转移至新项目集下。";
$lang->product->changeProgramError = "{$lang->productCommon}{$lang->SRCommon}已经关联到项目,请取消关联后再操作";
$lang->product->changeLineError = "产品线下已有产品,不可修改所属项目集。";
+7 -2
View File
@@ -21,6 +21,7 @@
<?php js::set('projectPathList', $projectPathList);?>
<style>
#changeProgram .icon-project {padding-right: 5px;}
#changeProgram .modal-body {padding-top: 10px;}
</style>
<div id="mainContent" class="main-content">
<div class="center-block">
@@ -115,6 +116,8 @@
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="icon icon-close"></i></button>
<?php if($canChangeProgram):?>
<h4 class="modal-title"><?php echo $lang->product->changeProgram;?></h4>
<?php else:?>
<h4 class="modal-title"><?php echo sprintf($lang->product->changeProgramTip, $product->name);?></h4>
<?php endif;?>
</div>
<div class="modal-body">
@@ -123,9 +126,11 @@
<tr>
<th class='text-left'><?php echo $lang->product->notChangeProgramTip;?></th>
</tr>
<?php foreach($linkStoriesProjects as $project):?>
<?php foreach($linkStoriesProjects as $projectID => $projectName):?>
<tr>
<td><i class="icon icon-project"></i><?php echo $project;?></td>
<td>
<?php echo html::a($this->createLink('projectstory', 'story', 'projectID=' . $projectID), "<i class='icon icon-project'></i>" . $projectName, '', "title='$projectName'");?>
</td>
</tr>
<?php endforeach;?>
<?php endif;?>
+13 -2
View File
@@ -219,6 +219,17 @@ $('[data-toggle="popover"]').popover();
$('#planForm').submit(function()
{
/* Clear all error messages. */
$('input[name^=begin]').each(function()
{
var beginDateID = $(this).attr('id');
if(beginDateID == 'begin%i%') return;
var endDateID = beginDateID.replace('begin', 'end');
$('#help' + beginDateID).remove();
$('#help' + endDateID).remove();
});
var submitForm = true;
$('input[name^=begin]').each(function()
{
@@ -231,11 +242,11 @@ $('#planForm').submit(function()
$('#help' + beginDateID).remove();
$('#help' + endDateID).remove();
// Invalid data is skipped.
/* Invalid data is skipped. */
var nameVal = $('#' + nameID).val()
if(!nameVal) return;
// Check if the begin date is empty.
/* Check if the begin date is empty. */
if(!beginDate)
{
submitForm = false;
+5
View File
@@ -2005,17 +2005,22 @@ class project extends control
$response['newProducts'] = html::select("newProducts", array('0' => '') + $newProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");
$multiLinkedProducts = $this->project->getMultiLinkedProducts($projectID);
$canChange = true;
if($multiLinkedProducts)
{
$multiLinkedProjects = array();
$programIdList = $this->dao->select('id, program')->from(TABLE_PRODUCT)->where('id')->in(array_keys($multiLinkedProducts))->fetchPairs();
foreach($multiLinkedProducts as $productID => $product)
{
if($programIdList[$productID] != $newTopPGM) $canChange = false;
$multiLinkedProjects[$productID] = $this->loadModel('product')->getProjectPairsByProduct($productID);
}
$response['result'] = false;
$response['message'] = $multiLinkedProducts;
$response['multiLinkedProjects'] = $multiLinkedProjects;
}
if($canChange) return true;
echo json_encode($response);
}
+3 -1
View File
@@ -14,7 +14,7 @@ $.zui.Picker.DEFAULTS.onChange = function(event)
var $select = $(this);
var selectPicker = $select.data('zui.picker');
if(selectPicker) selectPicker.updateOptionList([newItem]);
if(selectPicker) selectPicker.updateOptionList([$.extend({}, newItem)]);
});
}
@@ -111,6 +111,8 @@ function addItem(obj)
function deleteItem(obj)
{
if($('#teamForm .table tbody').children().length < 2) return false;
$(obj).closest('tr').find('.picker .picker-selection-remove').click();
$(obj).closest('tr').remove();
}
+3 -10
View File
@@ -134,19 +134,12 @@
<?php if($project->grade > 1):?>
<i class='icon icon-program text-muted'></i>
<?php
$end = end($programList);
reset($programList);
$names = '';
foreach($programList as $id => $name)
{
if($name != $end)
{
echo common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) . '/ ' : $name . '/ ';
}
else
{
echo common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) : $name;
}
$names .= common::hasPriv('program', 'product') ? html::a($this->createLink('program', 'product', "programID=$id"), $name) . '/ ' : $name . '/ ';
}
echo rtrim($names, '/ ');
?>
<?php endif;?>
</div>
+9
View File
@@ -9,3 +9,12 @@
#assignedTo a {border-color: transparent;}
#assignedTo a:hover {border-color: rgba(0,0,0,.2);}
#childrenTable tbody > tr:nth-child(odd) {background-color: #f5f5f5;}
.c-id {width: 50px;}
.c-pri {width: 40px;}
.c-deadline {width: 100px;}
.c-assignedTo {width: 120px;}
.c-status {width: 80px;}
.c-consumedAB {width: 60px;}
.c-leftAB {width: 60px;}
.c-actions {width: 175px;}
+8 -8
View File
@@ -108,15 +108,15 @@
<table class='table table-hover table-fixed' id='childrenTable'>
<thead>
<tr class='text-center'>
<th class='w-50px'> <?php echo $lang->task->id;?></th>
<th class='w-40px'> <?php echo $lang->task->lblPri;?></th>
<th class='c-id'> <?php echo $lang->task->id;?></th>
<th class='c-lblPri'> <?php echo $lang->task->lblPri;?></th>
<th> <?php echo $lang->task->name;?></th>
<th class='w-100px'><?php echo $lang->task->deadline;?></th>
<th class='w-120px'> <?php echo $lang->task->assignedTo;?></th>
<th class='w-80px'> <?php echo $lang->task->status;?></th>
<th class='w-60px visible-lg'><?php echo $lang->task->consumedAB . $lang->task->lblHour;?></th>
<th class='w-60px visible-lg'><?php echo $lang->task->leftAB . $lang->task->lblHour;?></th>
<th class='w-170px'><?php echo $lang->actions;?></th>
<th class='c-deadline'><?php echo $lang->task->deadline;?></th>
<th class='c-assignedTo'> <?php echo $lang->task->assignedTo;?></th>
<th class='c-status'> <?php echo $lang->task->status;?></th>
<th class='visible-lg c-consumedAB'><?php echo $lang->task->consumedAB . $lang->task->lblHour;?></th>
<th class='visible-lg c-leftAB'><?php echo $lang->task->leftAB . $lang->task->lblHour;?></th>
<th class='c-actions'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>