Merge branch 'zenops_46' of https://gitlab.zcorp.cc/easycorp/zentaopms into zenops_46

This commit is contained in:
zhaoke
2022-12-20 08:47:55 +00:00
65 changed files with 233 additions and 173 deletions
+3
View File
@@ -153,6 +153,9 @@ zentaoxx:
sed -i "s/'..\/..\/common\/view\/header.html.php'/\$$app->getModuleRoot() . 'common\/view\/header.html.php'/g" zentaoxx/extension/xuan/conference/view/admin.html.php
sed -i "s/'..\/..\/common\/view\/footer.html.php'/\$$app->getModuleRoot() . 'common\/view\/footer.html.php'/g" zentaoxx/extension/xuan/conference/view/admin.html.php
sed -i "s/\$$this->im->userGetChangedPassword()/array()/" zentaoxx/extension/xuan/im/control.php
sed -i "/.*->getAllDepts();/d" zentaoxx/extension/xuan/im/ext/bot/default.bot.php
sed -i "s/lang->user->status/lang->user->clientStatus/" zentaoxx/extension/xuan/im/ext/bot/default.bot.php
sed -i "s/.*->getRoleList();/\$$depts = \$$this->im->loadModel('dept')->getDeptPairs();\n\$$deptList = array_map(function(\$$k, \$$v) {return (object)array('id' => \$$k, 'name' => \$$v);}, array_keys(\$$depts), \$$depts);\n\$$roleList = \$$this->im->lang->user->roleList;/" zentaoxx/extension/xuan/im/ext/bot/default.bot.php
echo "ALTER TABLE \`zt_user\` ADD \`pinyin\` varchar(255) NOT NULL DEFAULT '' AFTER \`realname\`;" >> zentaoxx/db/xuanxuan.sql
mkdir zentaoxx/tools; cp tools/cn2tw.php zentaoxx/tools; cd zentaoxx/tools; php cn2tw.php
cp tools/en2other.php zentaoxx/tools; cd zentaoxx/tools; php en2other.php ../
+1 -3
View File
@@ -36,9 +36,7 @@ class taskRecordEstimateEntry extends entry
if(!$data) return $this->error('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$effort = new stdclass();
if($issetEffort and $data->data->efforts) $effort = $data->data->efforts;
if(!$issetEffort and $data->data->estimates) $effort = $data->data->estimates;
$effort = $data->data->efforts ? $data->data->efforts : new stdclass();
return $this->send(200, array('effort' => $effort));
}
+1 -1
View File
@@ -375,7 +375,7 @@ class baseControl
/**
* 如果客户端是手机的话,视图文件增加m.前缀。
* If the clent is mobile, add m. as prefix for view file.
* If the client is mobile, add m. as prefix for view file.
*
* @access public
* @return void
+1 -1
View File
@@ -1081,7 +1081,7 @@ class baseRouter
}
/**
* 从HTTP_ACCEPT_LANGUAGE中提出去支持的语言。
* 从HTTP_ACCEPT_LANGUAGE中剔除去支持的语言。
* Parse the lang str from HTTP_ACCEPT_LANGUAGE header.
*
* @access public
+2 -3
View File
@@ -19,12 +19,11 @@
<?php js::set('branchID', $bug->branch);?>
<?php js::set('errorNoExecution', $lang->bug->noExecution);?>
<?php js::set('errorNoProject', $lang->bug->noProject);?>
<?php $browseLink = $app->session->bugList ? $app->session->bugList : inlink('browse', "productID=$bug->product");?>
<?php if(strpos($_SERVER["QUERY_STRING"], 'isNotice=1') === false):?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php if(!isonlybody()):?>
<?php echo html::a($browseLink, '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary'");?>
<?php echo html::backButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "btn btn-secondary");?>
<div class="divider"></div>
<?php endif;?>
<div class="page-title">
@@ -92,7 +91,7 @@
?>
<div class='main-actions'>
<div class="btn-toolbar">
<?php common::printBack($browseLink);?>
<?php echo html::backButton('<i class="icon icon-back icon-goback"></i> ' . $lang->goback, "id='back' title='{$lang->goback}{$lang->backShortcutKey}'", 'btn');?>
<?php if(!$bug->deleted):?>
<div class='divider'></div>
<?php echo $this->bug->buildOperateMenu($bug, 'view');?>
+19 -15
View File
@@ -183,7 +183,8 @@ class build extends control
$builds = $this->build->getBuildPairs($build->product, 'all', 'noempty,notrunk,singled,separate', $build->project, 'project', $build->builds, false);
}
$executions = $this->product->getExecutionPairsByProduct($build->product, $build->branch, 'id_desc', $this->session->project, 'stagefilter');
$executions = $this->product->getExecutionPairsByProduct($build->product, $build->branch, 'id_desc', $this->session->project, 'stagefilter');
$executionType = $build->execution ? $this->execution->getByID($build->execution) : '';
if($build->execution and !isset($executions[$build->execution])) $executions[$build->execution] = $this->loadModel('execution')->getById($build->execution)->name;
/* Get stories and bugs. */
@@ -218,6 +219,7 @@ class build extends control
$this->view->orderBy = $orderBy;
$this->view->oldBranch = $oldBranch;
$this->view->executions = $executions;
$this->view->executionType = (!empty($executionType) and $executionType->type == 'stage') ? 1 : 0;
$this->view->productGroups = $productGroups;
$this->view->products = $products;
$this->view->users = $this->loadModel('user')->getPairs('noletter', $build->builder);
@@ -302,7 +304,8 @@ class build extends control
$objectID = $build->execution;
}
$executions = $this->loadModel('execution')->getPairs($this->session->project, 'all', 'empty');
$executions = $this->loadModel('execution')->getPairs($this->session->project, 'all', 'empty');
$executionType = $build->execution ? $this->execution->getByID($build->execution) : '';
$this->commonActions($build->project);
@@ -329,19 +332,20 @@ class build extends control
/* Assign. */
$this->view->canBeChanged = common::canBeChanged('build', $build); // Determines whether an object is editable.
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->build = $build;
$this->view->buildPairs = $this->build->getBuildPairs(0, 'all', 'noempty,notrunk', $objectID, $objectType);
$this->view->builds = $this->build->getByList(array_keys($this->view->buildPairs));
$this->view->executions = $executions;
$this->view->actions = $this->loadModel('action')->getList('build', $buildID);
$this->view->link = $link;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->bugs = $bugs;
$this->view->type = $type;
$this->view->bugPager = $bugPager;
$this->view->branchName = empty($branchName) ? $this->lang->branch->main : $branchName;
$this->view->childBuilds = empty($build->builds) ? array() : $this->dao->select('id,name,bugs,stories')->from(TABLE_BUILD)->where('id')->in($build->builds)->fetchAll();
$this->view->build = $build;
$this->view->buildPairs = $this->build->getBuildPairs(0, 'all', 'noempty,notrunk', $objectID, $objectType);
$this->view->builds = $this->build->getByList(array_keys($this->view->buildPairs));
$this->view->executions = $executions;
$this->view->actions = $this->loadModel('action')->getList('build', $buildID);
$this->view->link = $link;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->bugs = $bugs;
$this->view->type = $type;
$this->view->bugPager = $bugPager;
$this->view->branchName = empty($branchName) ? $this->lang->branch->main : $branchName;
$this->view->childBuilds = empty($build->builds) ? array() : $this->dao->select('id,name,bugs,stories')->from(TABLE_BUILD)->where('id')->in($build->builds)->fetchAll();
$this->view->executionType = (!empty($executionType) and $executionType->type == 'stage') ? 1 : 0;
if($this->app->getViewType() == 'json')
{
+1 -2
View File
@@ -20,8 +20,7 @@ function loadBranches(productID)
oldBranch = productGroups[productID]['branches'];
}
projectID = currentTab == 'execution' ? executionID : projectID;
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0&param=active&projectID=' + projectID + '&withMainBranch=true&isSiblings=no&fieldID=0&multiple=multiple'), function(data)
$.get(createLink('branch', 'ajaxGetBranches', 'productID=' + productID + '&oldBranch=0&param=active&projectID=' + $('#execution').val() + '&withMainBranch=true&isSiblings=no&fieldID=0&multiple=multiple'), function(data)
{
if(data)
{
+1
View File
@@ -34,6 +34,7 @@ $lang->build->branch = 'Platform/Branch';
$lang->build->branchAll = 'All associated %s';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->executionAB = 'execution';
$lang->build->integrated = 'Integrated';
$lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
+1
View File
@@ -34,6 +34,7 @@ $lang->build->branch = 'Platform/Branch';
$lang->build->branchAll = 'All associated %s';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->executionAB = 'execution';
$lang->build->integrated = 'Integrated';
$lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
+1
View File
@@ -34,6 +34,7 @@ $lang->build->branch = 'Plateforme/Branche';
$lang->build->branchAll = 'All associated %s';
$lang->build->branchName = '%s';
$lang->build->execution = $lang->executionCommon;
$lang->build->executionAB = 'execution';
$lang->build->integrated = 'Integrated';
$lang->build->singled = 'Singled';
$lang->build->builds = 'Included Builds';
+1
View File
@@ -34,6 +34,7 @@ $lang->build->branch = '平台/分支';
$lang->build->branchAll = '所有关联%s';
$lang->build->branchName = '所属%s';
$lang->build->execution = '所属' . $lang->executionCommon;
$lang->build->executionAB = '所属执行';
$lang->build->integrated = '集成版本';
$lang->build->singled = '单一版本';
$lang->build->builds = '包含版本';
+25 -2
View File
@@ -256,10 +256,11 @@ class buildModel extends model
->beginIF(strpos($params, 'hasdeleted') === false)->andWhere('deleted')->eq(0)->fi()
->fetchPairs();
}
$branchPairs = $this->dao->select('id,name')->from(TABLE_BRANCH)->fetchPairs();
$shadows = $this->dao->select('shadow')->from(TABLE_RELEASE)->where('product')->in($products)->fetchPairs('shadow', 'shadow');
$branchs = strpos($params, 'separate') === false ? "0,$branch" : $branch;
$allBuilds = $this->dao->select('t1.id, t1.name, t1.execution, t1.date, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t4.name as branchName, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
$allBuilds = $this->dao->select('t1.id, t1.name, t1.branch, t1.execution, t1.date, t1.deleted, t2.status as objectStatus, t3.id as releaseID, t3.status as releaseStatus, t5.type as productType')->from(TABLE_BUILD)->alias('t1')
->beginIF($objectType === 'execution')->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.execution = t2.id')->fi()
->beginIF($objectType === 'project')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')->fi()
->leftJoin(TABLE_RELEASE)->alias('t3')->on("FIND_IN_SET(t1.id,t3.build)")
@@ -289,7 +290,29 @@ class buildModel extends model
if((strpos($params, 'withexecution') !== false) and $build->execution and isset($executions[$build->execution])) continue;
if($build->deleted == 1) $build->name .= ' (' . $this->lang->build->deleted . ')';
$branchName = $build->branchName ? $build->branchName : $this->lang->branch->main;
if(!empty($build->branch))
{
$branchName = '';
foreach(explode(',', $build->branch) as $buildBranch)
{
if(empty($buildBranch))
{
$branchName .= $this->lang->branch->main;
}
else
{
$branchName .= isset($branchPairs[$buildBranch]) ? $branchPairs[$buildBranch] : '';
}
$branchName .= ',';
}
$branchName = trim($branchName, ',');
}
else
{
$branchName = $this->lang->branch->main;
}
$buildName = $build->name;
if(strpos($params, 'withbranch') !== false and $build->productType != 'normal') $buildName = $branchName . '/' . $buildName;
+1 -1
View File
@@ -64,7 +64,7 @@
</td>
</tr>
<?php elseif(!empty($multipleProject)):?>
<th class='w-120px'><?php echo $lang->build->execution;?></th>
<th class='w-120px'><?php echo $executionType ? $lang->build->executionAB : $lang->build->execution;?></th>
<td id='executionsBox'><?php echo html::select('execution', $executions, $build->execution, "class='form-control chosen' required $disabled");?></td>
<td><?php if($disabled) echo $lang->build->notice->changeExecution;?></td>
<?php endif;?>
+1 -1
View File
@@ -384,7 +384,7 @@ tbody tr td:first-child input {display: none;}
</tr>
<?php if($build->execution):?>
<tr>
<th><?php echo empty($multipleProject) ? $lang->build->project : $lang->build->execution;?></th>
<th><?php echo empty($multipleProject) ? $lang->build->project :($executionType ? $lang->build->executionAB : $lang->build->execution);?></th>
<td><?php echo zget($executions, $build->execution);?></td>
</tr>
<?php else:?>
+5
View File
@@ -15,6 +15,11 @@ $editorLang = isset($editorLangs[$app->getClientLang()]) ? $editorLangs[$app->
/* set uid for upload. */
$uid = uniqid('');
?>
<style>
<?php foreach($editor['id'] as $editorID):?>
<?php echo "textarea#{$editorID} {display:none}";?>
<?php endforeach?>
</style>
<?php js::import($jsRoot . 'kindeditor/kindeditor.min.js'); ?>
<?php js::import($jsRoot . "kindeditor/lang/{$editorLang}.js");?>
<script>
+2
View File
@@ -306,6 +306,7 @@ class docModel extends model
if($lib->acl == 'private' and $lib->acl == 'custom') $lib->users .= ',' . $libCreatedBy ? $libCreatedBy : $openedBy;
}
}
if($oldLib->acl != $lib->acl and $lib->acl == 'open') $lib->users = '';
$lib->name = trim($lib->name); //Temporary treatment: Code for bug #15528.
$this->dao->update(TABLE_DOCLIB)->data($lib)->autoCheck()
@@ -1528,6 +1529,7 @@ class docModel extends model
->where("CONCAT(',', t2.users, ',')")->like("%,{$this->app->user->account},%")
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->projects)->fi()
->fetchPairs();
}
+1 -1
View File
@@ -56,7 +56,7 @@
.modal-title {font-size: 14px !important; font-weight: 700 !important;}
#basicInfoBox tfoot td {padding-bottom: 0;}
</style>
<?php $backLink = $this->createLink('doc', 'objectlibs', "type=$type&objectID=$objectID&libID={$lib->id}&docID={$doc->id}") . "#app={$this->app->tab}";?>
<?php $backLink = $app->session->docList ? $app->session->docList : $this->createLink('doc', 'objectlibs', "type=$type&objectID=$objectID&libID={$lib->id}&docID={$doc->id}") . "#app={$this->app->tab}";?>
<div id="mainContent" class="main-content">
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
+3 -1
View File
@@ -3132,6 +3132,7 @@ class execution extends control
$unmodifiableProducts = array();
$unmodifiableBranches = array();
$linkedStoryIDList = array();
$linkedBranchIdList = array();
foreach($linkedProducts as $productID => $linkedProduct)
{
$linkedBranches[$productID] = array();
@@ -3139,6 +3140,7 @@ class execution extends control
foreach($branches[$productID] as $branchID => $branch)
{
$linkedBranches[$productID][$branchID] = $branchID;
$linkedBranchIdList[$branchID] = $branchID;
if(!empty($executionStories[$productID][$branchID]))
{
array_push($unmodifiableProducts, $productID);
@@ -3158,7 +3160,7 @@ class execution extends control
$this->view->unmodifiableBranches = $unmodifiableBranches;
$this->view->linkedBranches = $linkedBranches;
$this->view->linkedStoryIDList = $linkedStoryIDList;
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($allProducts), $execution->project, 'ignoreNormal|noclosed');
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($allProducts), $execution->project, 'ignoreNormal|noclosed', $linkedBranchIdList);
$this->view->allBranches = $this->execution->getBranchByProduct(array_keys($allProducts), $execution->project, 'ignoreNormal');
$this->display();
+1 -1
View File
@@ -10,9 +10,9 @@
* @link http://www.zentao.net
*/
?>
<?php js::import($this->config->webRoot . 'js/echarts/echarts.common.min.js'); ?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::import($this->config->webRoot . 'js/echarts/echarts.common.min.js'); ?>
<?php js::set('type', $type);?>
<?php js::set('chartData', $chartData);?>
<?php js::set('YUnit', $lang->execution->count); ?>
+1 -1
View File
@@ -194,7 +194,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['18.0.beta2'][] = array('title' => "We have optimized the product with multi-branches/multi-platforms. It's supported to create siblings stories. It's possible for Plan, Build, and Release to link requirements or bugs beyond their parent branch. 5 BI big screens are newly added. ZenTao Client has implemented the robot chatting mechanism.", 'desc' => '');
$lang->misc->feature->all['18.0.beta2'][] = array('title' => "We have optimized the product with multi-branches/multi-platforms. It's supported to create siblings stories. It's possible for Plan, Build, and Release to link requirements or bugs beyond their parent branch. ZenTao Client has implemented the robot chatting mechanism.", 'desc' => '');
$lang->misc->feature->all['18.0.beta1'][] = array('title' => "Multiple core processes in ZenTao are improved: A project without any product linked in is able to be created, as well as creating projects without sprints/iterations linked in; projects are able to link products beyond the father program; switch easily between ZenTao Lite mode and Full Lifecycle Management mode.", 'desc' => '');
$lang->misc->feature->all['17.8'][] = array('title' => "We have optimized the color of status in lists, as well as the dashboard color. At the same time, the page of the task effort has been improved.", 'desc' => '');
$lang->misc->feature->all['17.7'][] = array('title' => "The table is optimized in the transition version. At the same time, we have added the new feature of Work Order and get the Feedback features improved as well. Fix bugs.", 'desc' => '');
+1 -1
View File
@@ -194,7 +194,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['18.0.beta2'][] = array('title' => "We have optimized the product with multi-branches/multi-platforms. It's supported to create siblings stories. It's possible for Plan, Build, and Release to link requirements or bugs beyond their parent branch. 5 BI big screens are newly added. ZenTao Client has implemented the robot chatting mechanism.", 'desc' => '');
$lang->misc->feature->all['18.0.beta2'][] = array('title' => "We have optimized the product with multi-branches/multi-platforms. It's supported to create siblings stories. It's possible for Plan, Build, and Release to link requirements or bugs beyond their parent branch. ZenTao Client has implemented the robot chatting mechanism.", 'desc' => '');
$lang->misc->feature->all['18.0.beta1'][] = array('title' => "Multiple core processes in ZenTao are improved: A project without any product linked in is able to be created, as well as creating projects without sprints/iterations linked in; projects are able to link products beyond the father program; switch easily between ZenTao Lite mode and Full Lifecycle Management mode.", 'desc' => '');
$lang->misc->feature->all['17.8'][] = array('title' => "We have optimized the color of status in lists, as well as the dashboard color. At the same time, the page of the task effort has been improved.", 'desc' => '');
$lang->misc->feature->all['17.7'][] = array('title' => "The table is optimized in the transition version. At the same time, we have added the new feature of Work Order and get the Feedback features improved as well. Fix bugs.", 'desc' => '');
+1 -1
View File
@@ -194,7 +194,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['18.0.beta2'][] = array('title' => "We have optimized the product with multi-branches/multi-platforms. It's supported to create siblings stories. It's possible for Plan, Build, and Release to link requirements or bugs beyond their parent branch. 5 BI big screens are newly added. ZenTao Client has implemented the robot chatting mechanism.", 'desc' => '');
$lang->misc->feature->all['18.0.beta2'][] = array('title' => "We have optimized the product with multi-branches/multi-platforms. It's supported to create siblings stories. It's possible for Plan, Build, and Release to link requirements or bugs beyond their parent branch. ZenTao Client has implemented the robot chatting mechanism.", 'desc' => '');
$lang->misc->feature->all['18.0.beta1'][] = array('title' => "Multiple core processes in ZenTao are improved: A project without any product linked in is able to be created, as well as creating projects without sprints/iterations linked in; projects are able to link products beyond the father program; switch easily between ZenTao Lite mode and Full Lifecycle Management mode.", 'desc' => '');
$lang->misc->feature->all['17.8'][] = array('title' => "We have optimized the color of status in lists, as well as the dashboard color. At the same time, the page of the task effort has been improved.", 'desc' => '');
$lang->misc->feature->all['17.7'][] = array('title' => "The table is optimized in the transition version. At the same time, we have added the new feature of Work Order and get the Feedback features improved as well. Fix bugs.", 'desc' => '');
+1 -1
View File
@@ -194,7 +194,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['18.0.beta2'][] = array('title' => '优化多分支/多平台产品,支持创建孪生需求,计划、版本、发布支持跨分支关联需求和bug,新增5个BI大屏,并且禅道客户端实现了机器人会话机制。', 'desc' => '');
$lang->misc->feature->all['18.0.beta2'][] = array('title' => '优化多分支/多平台产品,支持创建孪生需求,计划、版本、发布支持跨分支关联需求和bug,并且禅道客户端实现了机器人会话机制。', 'desc' => '');
$lang->misc->feature->all['18.0.beta1'][] = array('title' => '主要对禅道多项核心流程进行改进,新增项目型项目、无迭代项目;支持项目跨项目集关联产品;支持轻量管理模式和全生命周期管理模式进行切换。', 'desc' => '');
$lang->misc->feature->all['17.8'][] = array('title' => '列表状态颜色、仪表盘颜色的改版和任务日志页面的优化。', 'desc' => '');
$lang->misc->feature->all['17.7'][] = array('title' => '过渡版本表格优化完成。新增工单功能,优化了反馈功能。修复Bug。', 'desc' => '');
+1 -1
View File
@@ -344,7 +344,7 @@ class myModel extends model
->andWhere('t2.deleted')->eq(0)
->andWhere('t1.id')->in(array_keys($objectIDList))
->orderBy($orderBy)
->page($pager)
->page($pager, 't1.id')
->fetchAll('id');
}
elseif($objectType == 'requirement' or $objectType == 'story' or $objectType == 'bug')
+1 -1
View File
@@ -1314,7 +1314,7 @@ class productModel extends model
->fetchAll('id');
/* Determine how to display the name of the program. */
$programList = $this->loadModel('program')->getParentPairs('', 'noclosed');
$programList = $this->loadModel('program')->getParentPairs('', 'all');
foreach($projectList as $id => $project)
{
$projectList[$id]->programName = $project->parent ? zget($programList, $project->parent, '') : '';
+1 -1
View File
@@ -80,7 +80,7 @@ class productplan extends control
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $planID));
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => 'parent.refreshPlan()'));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink($this->app->rawModule, 'browse', "productID=$productID&branch=$branchID&browseType=all")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink($this->app->rawModule, 'browse', "productID=$productID")));
}
$this->commonAction($productID, $branchID);
+2 -2
View File
@@ -1250,7 +1250,7 @@ class programModel extends model
* Get program parent pairs
*
* @param string $model
* @param string $mode
* @param string $mode noclosed|all
* @param bool $showRoot
* @access public
* @return array
@@ -1268,7 +1268,7 @@ class programModel extends model
$treeMenu = array();
foreach($modules as $module)
{
if(strpos(",{$this->app->user->view->programs},", ",{$module->id},") === false and (!$this->app->user->admin)) continue;
if(strpos($mode, 'all') !== false and strpos(",{$this->app->user->view->programs},", ",{$module->id},") === false and (!$this->app->user->admin)) continue;
$moduleName = $showRoot ? '/' : '';
$parentModules = explode(',', $module->path);
+3 -1
View File
@@ -2236,6 +2236,7 @@ class project extends control
}
$linkedBranches = array();
$linkedBranchIdList = array();
$branches = $this->project->getBranchesByProject($projectID);
$linkedProductIdList = empty($branches) ? '' : array_keys($branches);
$allProducts = $this->program->getProductPairs($project->parent, 'all', 'noclosed', $linkedProductIdList);
@@ -2253,6 +2254,7 @@ class project extends control
foreach($branches[$productID] as $branchID => $branch)
{
$linkedBranches[$productID][$branchID] = $branchID;
$linkedBranchIdList[$branchID] = $branchID;
if(!empty($projectStories[$productID][$branchID]) or !empty($projectBranches[$productID][$branchID]))
{
@@ -2263,7 +2265,7 @@ class project extends control
}
}
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), 'ignoreNormal|noclosed');
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), 'ignoreNormal|noclosed', $linkedBranchIdList);
if($this->config->systemMode == 'ALM')
{
$topProgramID = $project->parent ? $this->program->getTopByPath($project->path) : 0;
+2
View File
@@ -6,3 +6,5 @@
.c-days {width: 100px;}
.c-hours {width: 90px;}
.c-limited {width: 110px;}
.picker-drop-menu[id^="pickerDropMenu-pk_"] .picker-option-list > .picker-user-option,
.picker-drop-menu[id*=" pickerDropMenu-pk_"] .picker-option-list > .picker-user-option {display: flex; align-items: center;}
+3
View File
@@ -131,6 +131,9 @@ $(function()
$('#daysBox').removeClass('hidden');
}
})
var hasProduct = $('[name=hasProduct]:checked').val();
if(hasProduct == 0) $('.productsBox').parent().addClass('hidden')
});
/**
+2 -2
View File
@@ -78,9 +78,9 @@ class projectreleaseModel extends model
$branchName = '';
if($release->branch != 'normal')
{
foreach(explode(',', $release->branch) as $releaseBranch)
foreach(explode(',', trim($release->branch)) as $releaseBranch)
{
$branchName .= $this->loadModel('branch')->getById($releaseBranch);
$branchName .= $this->loadModel('branch')->getById($releaseBranch, $release->product);
$branchName .= ',';
}
$branchName = trim($branchName, ',');
+1 -1
View File
@@ -89,7 +89,7 @@ class releaseModel extends model
$branchName = '';
if($release->branch != 'normal')
{
foreach(explode(',', $release->branch) as $releaseBranch)
foreach(explode(',', trim($release->branch, ',')) as $releaseBranch)
{
$branchName .= $this->loadModel('branch')->getById($releaseBranch);
$branchName .= ',';
+1 -1
View File
@@ -23,7 +23,7 @@
</div>
<form id='repoForm' method='post' class='form-ajax'>
<table class='table table-form'>
<?php if($this->app->tab =='project'):?>
<?php if($this->app->tab == 'project' or $this->app->tab == 'execution'):?>
<?php echo html::hidden('product', implode(',', array_keys($products)));?>
<?php else:?>
<tr>
+3 -3
View File
@@ -46,7 +46,7 @@ section.active {border: 1px solid rgb(0, 166, 255);}
#infoList > li.dropdown .dropdown-menu > li {line-height: 1; height: 20px;}
#infoList > li.dropdown .dropdown-menu > li .todoStatus {display: inline-block; width: 80px;}
#actionData {width: 525px; height: 330px; margin: 0px 20px;}
#actionData {width: 525px; height: 330px; margin: 0px 15px;}
#actionData > div {margin-top: 13px;}
#actionData > div > ul > li {margin-bottom: 3px; cursor: default;}
#actionData > div > ul > li .dropdown-menu {background-color: #000; padding: 5px; border: 1px solid #999;}
@@ -67,7 +67,7 @@ section.active {border: 1px solid rgb(0, 166, 255);}
#executionData table, #productData table {margin-bottom: 0px;}
#executionData table tr>th, #productData table tr>th {color: #fff !important;}
#executionData .c-story, #executionData .c-task, #executionData .c-bug {text-align: center; width: 105px;}
#productData {margin-left: 20px;}
#productData {margin-left: 12px;}
#productData .c-plan, #productData .c-requirement, #productData .c-story, #productData .c-closed {text-align: center; width: 105px;}
#productData .c-story {width: 115px;}
#productData .c-requirement {width: 140px;}
@@ -81,4 +81,4 @@ section.active {border: 1px solid rgb(0, 166, 255);}
.dataYearStat > div {margin-top: 5px;}
.dataYearStat .canvas {float: left; height: 305px; padding-left: 30px;}
.dataYearStat .canvas.left {width: 450px;}
.dataYearStat .canvas.right {width: 810px; float: right;}
.dataYearStat .canvas.right {width: 810px; float: right;}
+3
View File
@@ -516,9 +516,12 @@ class reportModel extends model
return $this->dao->select('t1.id, t1.name, t2.account as user, t1.deadline')->from(TABLE_TASK)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.assignedTo = t2.account')
->leftJoin(TABLE_EXECUTION)->alias('t3')->on('t1.execution = t3.id')
->leftJoin(TABLE_PROJECT)->alias('t4')->on('t1.project = t4.id')
->where('t1.assignedTo')->ne('')
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
->andWhere('t3.deleted')->eq(0)
->andWhere('t4.deleted')->eq(0)
->andWhere('t1.status')->in('wait,doing')
->andWhere('t3.status')->ne('suspended')
->andWhere('t1.deadline', true)->eq('0000-00-00')
+18 -8
View File
@@ -171,21 +171,27 @@ class story extends control
/* Record submit review action. */
$story = $this->dao->findById((int)$storyID)->from(TABLE_STORY)->fetch();
if($story->status == 'reviewing') $this->action->create('story', $storyID, 'submitReview');
if($story->status == 'reviewing')
{
foreach($storyIds as $idItem) $this->action->create('story', $idItem, 'submitReview');
}
if($objectID != 0)
{
$object = $this->dao->findById((int)$objectID)->from(TABLE_PROJECT)->fetch();
if($object->type != 'project')
{
$this->action->create('story', $storyID, 'linked2project', '', $object->project);
foreach($storyIds as $idItem)
{
$this->action->create('story', $idItem, 'linked2project', '', $object->project);
$actionType = $object->type == 'kanban' ? 'linked2kanban' : 'linked2execution';
if($object->multiple) $this->action->create('story', $storyID, $actionType, '', $objectID);
$actionType = $object->type == 'kanban' ? 'linked2kanban' : 'linked2execution';
if($object->multiple) $this->action->create('story', $idItem, $actionType, '', $objectID);
}
}
else
{
$this->action->create('story', $storyID, 'linked2project', '', $objectID);
foreach($storyIds as $idItem) $this->action->create('story', $idItem, 'linked2project', '', $objectID);
}
}
@@ -1908,12 +1914,11 @@ class story extends control
$productStoryList = array();
$productList = array();
$ignoreTwins = array();
$twinsCount = 0;
$twinsCount = array();
foreach($stories as $story)
{
if(!empty($ignoreTwins) and isset($ignoreTwins[$story->id]))
{
$twinsCount ++;
unset($stories[$story->id]);
continue;
}
@@ -1935,7 +1940,12 @@ class story extends control
if(!empty($story->twins))
{
foreach(explode(',', trim($story->twins, ',')) as $twinID) $ignoreTwins[$twinID] = $twinID;
$twinsCount[$story->id] = 0;
foreach(explode(',', trim($story->twins, ',')) as $twinID)
{
$twinsCount[$story->id] ++;
$ignoreTwins[$twinID] = $twinID;
}
}
}
+1 -1
View File
@@ -320,7 +320,7 @@ function loadPlanForTwins(productID, branch, branchIndex)
{
/* Load plan */
if(branch == '0') branch = '';
planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&branch=' + branch + '&planID=0&fieldID=' + branchIndex + '&needCreate=false&expired=unexpired&param=skipParent|forStory,' + config.currentMethod);
planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&branch=' + branch + '&planID=0&fieldID=' + branchIndex + '&needCreate=false&expired=unexpired&param=skipParent,forStory,' + config.currentMethod);
if(branchIndex > 0)
{
var $planIdBox = $('.addBranchesBox'+ branchIndex +' #planIdBox');
+2 -36
View File
@@ -866,6 +866,7 @@ class storyModel extends model
{
$this->dbh->exec("UPDATE " . TABLE_STORY . " SET twins = REPLACE(twins, ',$storyID,', ',') WHERE `product` = $oldStory->product");
$this->dao->update(TABLE_STORY)->set('twins')->eq('')->where('id')->eq($storyID)->orWhere('twins')->eq(',')->exec();
if(!dao::isError()) $this->loadModel('action')->create('story', $storyID, 'relieved');
}
elseif(!empty($oldStory->twins))
{
@@ -2228,41 +2229,6 @@ class storyModel extends model
if(empty($oldPlanID)) $story->plan = $planID;
if($oldStory->branch) $story->plan = $planID;
/* Append the plan id to plan field if product is multi and story is all branch. */
if($this->session->currentProductType != 'normal' and empty($story->branch))
{
$branchPlanPairs = $this->dao->select('branch, id as plan')->from(TABLE_PRODUCTPLAN)
->where('product')->eq($oldStory->product)
->andWhere('id')->in($oldStory->plan)
->fetchPairs();
foreach($branchPlanPairs as $branches => $planParis)
{
foreach(explode(',', $branches) as $branch)
{
$branchPlanPairs[$branch] = $planParis;
}
unset($branchPlanPairs[$branches]);
}
if($planID == 0 and !empty($oldStory->plan) and isset($branchPlanPairs[0]) and $branchPlanPairs[0] != $planID) $unlinkPlans[$branchPlanPairs[0]] = empty($unlinkPlans[$branchPlanPairs[0]]) ? $storyID : "{$unlinkPlans[$branchPlanPairs[0]]},$storyID";
if($planID != 0)
{
if(!empty($oldStory->plan))
{
foreach(explode(',', $plan->branch) as $planBranch)
{
if(isset($branchPlanPairs[$planBranch]) and $branchPlanPairs[$planBranch] != $planID)
{
$unlinkPlans[$branchPlanPairs[$planBranch]] = empty($unlinkPlans[$branchPlanPairs[$planBranch]]) ? $storyID : "{$unlinkPlans[$branchPlanPairs[$planBranch]]},$storyID";
}
}
}
foreach(explode(',', $plan->branch) as $planBranch) if(isset($branchPlanPairs[$planBranch])) $branchPlanPairs[$planBranch] = $planID;
$story->plan = $oldStory->plan ? implode(',', array_unique($branchPlanPairs)) : $planID;
$story->plan = trim($story->plan, ',');
if($story->plan != $oldStory->plan and !empty($planID)) $link2Plans[$planID] = empty($link2Plans[$planID]) ? $storyID : "{$link2Plans[$planID]},$storyID";
}
}
/* Change stage. */
if($planID)
{
@@ -6541,7 +6507,7 @@ class storyModel extends model
$fieldName = $changeInfo['field'];
$fieldValue = $changeInfo['new'];
if(strpos('product,branch,module,plan,spec,verify,files,reviewers', $fieldName) !== false) continue;
if(strpos('product,branch,module,plan,stage,stagedBy,spec,verify,files,reviewers', $fieldName) !== false) continue;
$syncFieldList[$fieldName] = $fieldValue;
}
+1 -1
View File
@@ -11,7 +11,7 @@ if(isset($twins))
<li class='active'><a data-toggle='tab' href='#affectedProjects'><?php echo $lang->story->affectedProjects;?> <?php $count = count($story->executions); if($count > 0) echo "<span class='label label-danger label-badge label-circle'>" . $count . "</span>" ?></a></li>
<li><a data-toggle='tab' href='#affectedBugs'><?php echo $lang->story->affectedBugs;?> <?php $count = count($story->bugs); if($count > 0) echo "<span class='label label-danger label-badge label-circle'>" . $count . "</span>" ?></a></li>
<li><a data-toggle='tab' href='#affectedCases'><?php echo $lang->story->affectedCases;?> <?php $count = count($story->cases); if($count > 0) echo "<span class='label label-danger label-badge label-circle'>" . $count . "</span>" ?></a></li>
<li><a data-toggle='tab' href='#affectedTwins'><?php if(count($twins) > 0) echo $lang->story->affectedTwins;?> <?php if(count($twins) > 0) echo "<span class='label label-danger label-badge label-circle'>" . count($twins) . "</span>" ?></a></li>
<li><a data-toggle='tab' href='#affectedTwins'><?php if(isset($twins) and count($twins) > 0) echo $lang->story->affectedTwins;?> <?php if(isset($twins) and count($twins) > 0) echo "<span class='label label-danger label-badge label-circle'>" . count($twins) . "</span>" ?></a></li>
</ul>
<div class='tab-content'>
<div class='tab-pane active' id='affectedProjects'>
+1 -1
View File
@@ -37,7 +37,7 @@
<td title='<?php echo $story->title;?>' class='text-left'>
<?php echo $story->title;?>
<?php if(!empty($story->twins)):?>
<span class='label label-outline label-badge'><?php echo "{$lang->story->twins}:"?> <span class='text-blue'><?php echo $twinsCount?></span></span>
<span class='label label-outline label-badge'><?php echo "{$lang->story->twins}:"?> <span class='text-blue'><?php echo $twinsCount[$story->id]?></span></span>
<?php endif;?>
</td>
<td class='story-<?php echo $story->status;?>'><?php echo $this->processStatus('story', $story);?></td>
+2 -1
View File
@@ -84,7 +84,8 @@ foreach(explode(',', $showFields) as $field)
</td>
<?php if(!$hiddenPlan):?>
<td class='text-left<?php echo zget($visibleFields, 'plan', ' hidden')?>'>
<?php echo html::select("plans[$storyID]", isset($plans[$story->product][$story->branch]) ? array('' => '') + $plans[$story->product][$story->branch] : '', $story->plan, "class='form-control picker-select' data-drop-width='auto'");?>
<?php $planDisabled = $story->parent < 0 ? "disabled='disabled'" : '';?>
<?php echo html::select("plans[$storyID]", isset($plans[$story->product][$story->branch]) ? array('' => '') + $plans[$story->product][$story->branch] : '', $story->plan, "class='form-control picker-select' data-drop-width='auto' $planDisabled");?>
</td>
<?php endif;?>
<td title='<?php echo $story->title?>'>
+1 -1
View File
@@ -22,7 +22,7 @@ foreach($twins as $twin)
echo "<li title='$title' class='twins'>";
echo "<span class='label {$labelClass} label-outline label-badge' title='$branch'>{$branch}</span> ";
echo "<span class='label label-outline' title='{$stage}'>{$stage}</span> ";
echo ($canViewLinkStory ? html::a($this->createLink('story', 'view', "id=$id", '', true), "$title", '', "class='$class viewlink' data-width='80%'") : "$title");
echo ($canViewLinkStory ? html::a($this->createLink('story', 'view', "id=$id", '', true), "$title", '', "class='$class viewlink' data-width='90%'") : "$title");
if($canRelieved) echo "<a class='unlink $hide' data-id='$id' data-toggle='popover'><i class='icon icon-unlink btn-info'></i></a>";
echo "</li>";
}
+1 -1
View File
@@ -34,7 +34,7 @@
<?php echo $lang->story->relievedTwinsRelation;?>
</label>
</div>
<div style="display: inline-block"><icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->story->relievedTwinsRelationTips;?>"></icon></div>
<div class="<?php echo !empty($story->twins) ? '' : 'hidden';?>" style="display: inline-block"><icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->story->relievedTwinsRelationTips;?>"></icon></div>
</td>
</tr>
<tr id='duplicateStoryBox' style='display:none'>
+11 -5
View File
@@ -117,13 +117,14 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
</div>
</td>
</tr>
<tr class='hidden switchBranch' >
<tr class='hidden' >
<th></th>
<td colspan="4" id="storyNoticeBranch">
<i class="icon-exclamation-sign"></i> <?php echo $lang->story->notice->branch;?>
</td>
</tr>
<tr class='<?php if($branches) echo "hidden"; ?> switchBranch'>
<?php if(!$hiddenPlan):?>
<th class='planTh'><?php echo $lang->story->planAB;?></th>
<td colspan="2">
<div class='input-group' id='planIdBox'>
@@ -141,6 +142,9 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
?>
</div>
</td>
<?php else:?>
<th class='planTh'><?php echo $lang->story->assignedTo;?></th>
<?php endif;?>
<td colspan='<?php echo $type == 'story' ? 2 : 1;?>' id='assignedToBox'>
<div class='input-group'>
<?php if(!$hiddenPlan):?>
@@ -405,10 +409,12 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
<script>
$(function(){parent.$('body.hide-modal-close').removeClass('hide-modal-close');})
var gap = $('#assignedTo').parent().parent().width();
$('#planIdBox').css('flex', '0 0 ' + gap + 'px')
$("#branches0").parent().parent().css('flex', '1 0 160px')
$("#modules0").parent().parent().css('flex', '1 0 160px')
setTimeout(() => {
gap = $('#assignedTo').parent().parent().width();
$('#planIdBox').css('flex', '0 0 ' + gap + 'px')
$("#branches0").parent().parent().css('flex', '1 0 160px')
$("#modules0").parent().parent().css('flex', '1 0 160px')
}, 600);
</script>
<?php include '../../common/view/footer.html.php';?>
+2 -1
View File
@@ -105,6 +105,7 @@ function loadProductBranches(productID)
$('.switchBranch').toggleClass('hidden');
$('.switchBranch').toggleClass('disable');
}
$('#storyNoticeBranch').closest('tr').addClass('hidden');
originProductType = newProductType;
$('tr[class^="addBranchesBox"]').remove();
@@ -215,7 +216,7 @@ function loadProductPlans(productID, branch)
var param = rawMethod == 'edit' ? 'skipParent|forStory' : 'skipParent';
var expired = config.currentMethod == 'create' ? 'unexpired' : '';
var planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&branch=' + branch + '&planID=' + $('#plan').val() + '&fieldID=&needCreate=true&expired='+ expired +'&param=skipParent|forStory|' + config.currentMethod);
var planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&branch=' + branch + '&planID=' + $('#plan').val() + '&fieldID=&needCreate=true&expired='+ expired +'&param=skipParent,forStory,' + config.currentMethod);
var $planIdBox = rawMethod == 'create' ? $('.switchBranch #planIdBox') : $('#planIdBox');
$planIdBox.load(planLink, function()
+1 -1
View File
@@ -2644,7 +2644,7 @@ class taskModel extends model
->beginIF($type == 'assignedTo' and $this->app->rawModule == 'my' and $this->app->rawMethod == 'work')->andWhere('t1.status')->notin('closed,cancel,pause')->fi()
->orderBy($orderBy)
->beginIF($limit > 0)->limit($limit)->fi()
->page($pager)
->page($pager, 't1.id')
->fetchAll('id');
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'task', false);
+2 -2
View File
@@ -78,8 +78,8 @@ foreach(explode(',', $config->task->create->requiredFields) as $field)
<span class="input-group-btn team-group hidden"><a class="btn br-0" href="#modalTeam" data-toggle="modal"><?php echo $lang->task->team;?></a></span>
</div>
</td>
<td>
<div class="checkbox-primary c-multipleTask affair" style='display: inline-block'>
<td colspan='2'>
<div class="checkbox-primary c-multipleTask affair" style='display: inline-block; margin-right: <?php echo common::checkNotCN() ? '-10px' : '-30px'?>'>
<input type="checkbox" name="multiple" value="1" id="multipleBox" /><label for="multipleBox" class="no-margin"><?php echo $lang->task->multiple;?></label>
</div>
<div class='hidden modeBox' style='display: inline-block'><?php echo html::radio('mode', $lang->task->modeList, !empty($task->mode) ? $task->mode: 'linear');?></div>
+1 -1
View File
@@ -138,7 +138,7 @@ function setStories()
var value = $('#story').val();
if(!stories) stories = '<select id="story" name="story"></select>';
$('#story').replaceWith(stories);
$('#story').val(value);
$('#story').val(value).attr('onchange', 'setPreview()');
$('#story_chosen').remove();
$('#story').next('.picker').remove();
$("#story").picker();
+1 -1
View File
@@ -37,7 +37,7 @@ class transferModel extends model
}
/**
* Commom Actions.
* Common Actions.
*
* @param int $model
* @access public
+2 -2
View File
@@ -390,7 +390,7 @@ class tree extends control
}
else
{
$this->view->optionMenu = $this->tree->getOptionMenu($module->root, $module->type, 0, $module->branch, 'noMainBranch');
$this->view->optionMenu = $this->tree->getOptionMenu($module->root, $module->type, 0, $module->branch, 'noMainBranch|nodeleted');
}
if($type == 'doc') $this->view->libs = $this->loadModel('doc')->getLibs('all', $extra = 'withObject', '', 0, 'book');
@@ -567,7 +567,7 @@ class tree extends control
$currentModuleID = (isset($currentModule->branch) and $currentModule->branch == 0) ? $currentModuleID : 0;
$output = html::select("$field", $optionMenu, $currentModuleID, "class='form-control' $changeFunc");
if(count($optionMenu) == 1 and $needManage !== 'false')
if(count($optionMenu) == 1 and $needManage !== 'false' and $viewType != 'task')
{
$output .= "<span class='input-group-addon'>";
$output .= html::a($this->createLink('tree', 'browse', "rootID=$rootID&view=$viewType&currentModuleID=0&branch=$branch", '', true), $this->lang->tree->manage, '', "class='text-primary' data-toggle='modal' data-type='iframe' data-width='95%'");
+5 -2
View File
@@ -92,11 +92,14 @@ class treeModel extends model
->beginIF($type == 'task')->andWhere('type')->eq('task')->fi()
->beginIF($type != 'task')->andWhere('type')->in("story,$type")->fi()
->beginIF($startModulePath)->andWhere('path')->like($startModulePath)->fi()
->beginIF($branch !== 'all' and $branch !== '' and $branch !== false)
->beginIF($branch !== 'all' and $branch !== '' and $branch !== false and strpos($param, 'noMainBranch') === false)
->andWhere("(branch")->eq(0)
->orWhere('branch')->eq($branch)
->markRight(1)
->fi()
->beginIF($branch !== 'all' and $branch !== '' and $branch !== false and strpos($param, 'noMainBranch') !== false)
->andWhere('branch')->eq($branch)
->fi()
->beginIF(strpos($param, 'nodeleted') !== false)->andWhere('deleted')->eq(0)->fi()
->orderBy('grade desc, `order`, type desc')
->get();
@@ -178,7 +181,7 @@ class treeModel extends model
$treeMenu = array();
foreach($branches as $branchID => $branch)
{
{
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, $type, $startModule, $branchID, $param));
$modules = array();
while($module = $stmt->fetch())
+1 -1
View File
@@ -189,7 +189,7 @@ function loadModules(branch)
if(typeof(branchID) == 'undefined') branchID = 0;
if(typeof(moduleID) == 'undefined') moduleID = 0;
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branchID + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=excludeModuleID=' + <?php echo $module->id;?> + ',noMainBranch&currentModuleID=' + moduleID);
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=' + type + '&branch=' + branchID + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=excludeModuleID=' + <?php echo $module->id;?> + ',noMainBranch,nodeleted&currentModuleID=' + moduleID);
$(moduleBox).load(link, function()
{
$(this).children('select').attr('id', 'parent').attr('name', 'parent');
+1 -1
View File
@@ -396,7 +396,7 @@ $config->delete['17_8'][] = 'extension/max/common/ext/lang/vi/crystal.php';
$config->delete['18_0'][] = 'extension/max/custom/ext/view/mode.zentaomax.html.hook.php';
$config->delete['18_0'][] = 'extension/max/my/ext/view/audit.html.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', 'projectplan', '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', 'gitea', 'gogs', 'transfer', 'port', 'zahost');
$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', 'projectplan', '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', 'gitea', 'gogs', 'transfer', 'port', 'zahost', 'zanode');
$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', 'gitea', 'gogs', 'zanode', 'zahost');
+1 -1
View File
@@ -38,7 +38,7 @@ if(!isset($config->installed) or !$config->installed) die(header('location: inst
/* Check for need upgrade. */
$config->installedVersion = $app->getInstalledVersion();
if($config->version != $config->installedVersion && file_exists('upgrade.php')) die(header('location: upgrade.php'));
if($config->version != $config->installedVersion) die(header('location: upgrade.php'));
/* Run the app. */
$common = $app->loadCommon();
+22 -22
View File
@@ -277,10 +277,10 @@
border-radius: 2px;
}
.ke-container.focus {
border-color: #0c64eb;
border-color: #2e7fff;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(12, 100, 235, .6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(12, 100, 235, .6);
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(46, 127, 255, .6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(46, 127, 255, .6);
}
.ke-container.ke-loading > .ke-toolbar,
.ke-container.ke-loading > .ke-edit,
@@ -327,7 +327,7 @@
.ke-toolbar .ke-on,
.ke-toolbar .ke-selected {
filter: alpha(opacity=100);
border-color: #cbd0db;
border-color: #c4c4c4;
opacity: 1;
}
.ke-toolbar .ke-selected {
@@ -347,7 +347,7 @@
line-height: 0;
border-top: 0;
border-bottom: 0;
border-left: 1px dotted #cbd0db;
border-left: 1px dotted #c4c4c4;
}
.ke-toolbar .ke-hr {
height: 1px;
@@ -369,7 +369,7 @@
overflow: auto;
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
font-size: 12px;
color: #3c4353;
color: #313c52;
resize: none;
background-color: #fff;
}
@@ -431,7 +431,7 @@
font-size: 12px;
text-align: left;
background-color: #fff;
border: 1px solid #b6bdcc;
border: 1px solid #b2b2b2;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 4px;
}
@@ -443,7 +443,7 @@
.ke-menu-item-on {
color: #fff;
text-decoration: none;
background-color: #0c64eb;
background-color: #2e7fff;
outline: 0;
}
.ke-menu-item-left {
@@ -482,7 +482,7 @@
/* colorpicker */
.ke-colorpicker {
background-color: #fff;
border: 1px solid #b6bdcc;
border: 1px solid #b2b2b2;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 4px;
}
@@ -516,13 +516,13 @@
}
.ke-colorpicker-cell-on {
color: #fff;
background-color: #0c64eb;
background-color: #2e7fff;
}
.ke-colorpicker-cell-on .ke-colorpicker-cell-color {
border: 2px solid #3c4353;
border: 2px solid #313c52;
}
.ke-colorpicker-cell-selected .ke-colorpicker-cell-color {
border: 2px solid #3c4353;
border: 2px solid #313c52;
}
/* dialog */
.ke-dialog {
@@ -719,11 +719,11 @@
padding: 0 12px;
margin: 0;
font-size: 12px;
color: #3c4353;
color: #313c52;
text-decoration: none;
background-color: #fff;
border: 1px solid #d6dae3;
border-color: #d6dae3;
border: 1px solid #d8dbde;
border-color: #d8dbde;
border-radius: 4px;
}
.ke-button:hover,
@@ -731,9 +731,9 @@
.ke-button:active,
.ke-button.active,
.open .dropdown-toggle.ke-button {
color: #3c4353;
color: #313c52;
background-color: #ebebeb;
border-color: #b2b9ca;
border-color: #b7bcc2;
-webkit-box-shadow: 0 2px 1px rgba(0, 0, 0, .1);
box-shadow: 0 2px 1px rgba(0, 0, 0, .1);
}
@@ -742,7 +742,7 @@
.open .dropdown-toggle.ke-button {
background-color: #d9d9d9;
background-image: none;
border-color: #b8bfce;
border-color: #bcc2c7;
-webkit-box-shadow: inset 0 4px 6px rgba(0, 0, 0, .15);
box-shadow: inset 0 4px 6px rgba(0, 0, 0, .15);
}
@@ -762,7 +762,7 @@ fieldset[disabled] .ke-button:active,
.ke-button[disabled].active,
fieldset[disabled] .ke-button.active {
background-color: #fff;
border-color: #d6dae3;
border-color: #d8dbde;
}
/* inputbox */
.ke-input-text {
@@ -790,10 +790,10 @@ fieldset[disabled] .ke-button.active {
}
.ke-input-text:focus,
.ke-input-text.focus {
border-color: #0c64eb;
border-color: #2e7fff;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(12, 100, 235, .6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(12, 100, 235, .6);
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(46, 127, 255, .6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(46, 127, 255, .6);
}
.ke-input-text[disabled] {
background: #eee;
+7 -11
View File
@@ -1,10 +1,3 @@
/*!
* ZUI: Zentao Kindeditor - v1.10.0 - 2022-04-19
* http://openzui.com
* GitHub: https://github.com/easysoft/zui.git
* Copyright (c) 2022 cnezsoft.com; Licensed MIT
*/
/******************************************************************************
* KindEditor - WYSIWYG HTML Editor for Internet
* Copyright (C) 2006-2013 kindsoft.net
@@ -304,7 +297,7 @@
],
fontSizeTable: ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'],
htmlTags: {
font: ['id', 'class', 'color', 'size', 'face', '.background-color'],
font: ['id', 'class', 'color', 'size', 'face', '.background-color', '.color', '.font-size', '.font-family'],
span: [
'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background',
'.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height'
@@ -10359,14 +10352,17 @@ KindEditor.plugin('pasteimage', function(K) {
var original = ev.originalEvent;
var clipboardItems = original.clipboardData && original.clipboardData.items;
var clipboardItem = null;
if(clipboardItems) {
if(clipboardItems)
{
var IMAGE_MIME_REGEX = /^image\/(p?jpeg|gif|png)$/i;
for (var i = 0; i < clipboardItems.length; i++)
{
if (IMAGE_MIME_REGEX.test(clipboardItems[i].type))
var dataType = clipboardItems[i].type;
if(options.pasteTextFirst && dataType.indexOf('text/') === 0) return;
if (IMAGE_MIME_REGEX.test(dataType))
{
clipboardItem = clipboardItems[i];
break;
if(!options.pasteTextFirst) break;
}
}
}
File diff suppressed because one or more lines are too long
+6 -12
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
6d5d77c11978c707cb8204353f640a3ecca6e046
v7.0.0-rc.3
@@ -35,6 +35,20 @@ $(function()
window.parent.appHeaderStyleUpdated = true;
window.open('xxc://setAppHeaderStyle/zentao-integrated/' + encodeURIComponent(JSON.stringify(clientHeaderStyle)), '_blank');
});
setTimeout(function() // Override confirm, prompt and alert methods.
{
window.confirm = function() {
console.warn('\"window.confirm\" is disabled in webview.');
return true;
};
window.prompt = function() {
console.warn('\"window.prompt\" is disabled in webview.');
};
window.alert = function(msg) {
const win = window.parent ? window.parent : window;
win.open(`xxc://webview/alert/${encodeURIComponent(msg)}`, '_blank');
};
});
</script>
<?php if($this->app->moduleName =='user' && $this->app->methodName == 'deny'): ?>
<script>
@@ -55,11 +55,15 @@ class zentaoBot extends xuanBot
$this->commands[] = array('command' => $command, 'alias' => $this->lang->commands->$command->alias, 'description' => $this->lang->commands->$command->description, 'internal' => true);
}
/* Backup user model of im module, load user module and restore. Use `$this->userModel` as user module from now on. */
$imUser = $this->im->user;
$this->userModel = $this->im->loadModel('user');
$this->im->user = $imUser;
$this->im->loadModel('task');
$this->im->loadModel('user');
$this->im->app->loadClass('pager', $static = true);
$this->users = array_filter($this->im->user->getPairs('noclosed|noletter'));
$this->users = array_filter($this->userModel->getPairs('noclosed|noletter'));
$this->taskStatusList = array_filter($this->im->lang->task->statusList);
$this->help = $this->lang->help;
@@ -408,7 +412,7 @@ class zentaoBot extends xuanBot
if($task->status != 'done' && $task->status != 'cancel') return sprintf($this->lang->errors->invalidStatus, $this->taskStatusList[$task->status]);
$task = $this->loadEntry('taskclose', 'post', array('taskID' => $taskID, 'comment' => $comment));
if($task->result == 'fail') return $task->message;
if(isset($task->result) && $task->result == 'fail') return $task->message;
$link = str_replace('x.php', 'index.php', helper::createLink('task', 'view', "taskID=$taskID", 'html'));
$messages = new stdClass();
@@ -687,7 +691,7 @@ class zentaoBot extends xuanBot
}
else
{
$tr .= "<td class='text-nowrap'>{$task->assignedTo->realname}</td>";
$tr .= "<td class='text-nowrap'>" . (empty($task->assignedTo) ? $lang->task->noAssigned : (is_object($task->assignedTo) ? $task->assignedTo->realname : $task->assignedTo)) . "</td>";
}
break;
case 'actions':
@@ -861,7 +865,7 @@ class zentaoBot extends xuanBot
'realStarted' => $realStarted,
'consumed' => $consumed,
));
if($task->result and $task->result == 'fail')
if(isset($task->result) and $task->result == 'fail')
{
$reply->messages[] = $task->message;
}
@@ -971,11 +975,11 @@ class zentaoBot extends xuanBot
{
$this->im->loadModel('user');
$user = $this->im->user->getByID($this->im->app->input['userID'], 'id');
$user = $this->userModel->getByID($this->im->app->input['userID'], 'id');
/* Authorize him and save to session. */
$user->rights = $this->im->user->authorize($user->account);
$user->groups = $this->im->user->getGroups($user->account);
$user->view = $this->im->user->grantUserView($user->account, $user->rights['acls'], $user->rights['projects']);
$user->rights = $this->userModel->authorize($user->account);
$user->groups = $this->userModel->getGroups($user->account);
$user->view = $this->userModel->grantUserView($user->account, $user->rights['acls'], $user->rights['projects']);
$user->admin = strpos($this->im->app->company->admins, ",{$user->account},") !== false;
global $app;
@@ -0,0 +1,4 @@
<?php
$lang->upgrade->upgradeXuanxuan = 'Upgrade Xuanxuan';
$lang->upgrade->archiveChangeNoticeTitle = 'Chat group archive change notice';
$lang->upgrade->archiveChangeNoticeContent = 'Due to the version update, the original archive feature has been changed, and your original archive discussion group has been set as a no-disturb message, please go to https://xuanim.com/book/xuanxuankehuduan/205.html for details.';
@@ -0,0 +1,4 @@
<?php
$lang->upgrade->upgradeXuanxuan = 'Upgrade Xuanxuan';
$lang->upgrade->archiveChangeNoticeTitle = 'Chat group archive change notice';
$lang->upgrade->archiveChangeNoticeContent = 'Due to the version update, the original archive feature has been changed, and your original archive discussion group has been set as a no-disturb message, please go to https://xuanim.com/book/xuanxuankehuduan/205.html for details.';
@@ -0,0 +1,4 @@
<?php
$lang->upgrade->upgradeXuanxuan = 'Upgrade Xuanxuan';
$lang->upgrade->archiveChangeNoticeTitle = 'Chat group archive change notice';
$lang->upgrade->archiveChangeNoticeContent = 'Due to the version update, the original archive feature has been changed, and your original archive discussion group has been set as a no-disturb message, please go to https://xuanim.com/book/xuanxuankehuduan/205.html for details.';
@@ -0,0 +1,4 @@
<?php
$lang->upgrade->upgradeXuanxuan = '升级喧喧';
$lang->upgrade->archiveChangeNoticeTitle = '存档功能变更通知';
$lang->upgrade->archiveChangeNoticeContent = '由于版本更新,原存档功能发生变更,已将您原存档讨论组状态设为消息免打扰,具体变更请移步 https://www.xuanim.com/book/xuanxuankehuduan/205.html ';