diff --git a/Makefile b/Makefile
index 0a0bb955f5..2435ae32e8 100644
--- a/Makefile
+++ b/Makefile
@@ -131,6 +131,8 @@ zentaoxx:
sed -i 's/commonModel::getLicensePropertyValue/extCommonModel::getLicensePropertyValue/g' zentaoxx/extension/xuan/im/control.php
sed -i 's/commonModel::getLicensePropertyValue/extCommonModel::getLicensePropertyValue/g' zentaoxx/extension/xuan/im/model/conference.php
sed -i 's/xxb_/zt_/g' zentaoxx/db/*.sql
+ sed -i "s#\$this->app->getModuleRoot() . 'im/apischeme.json'#\$this->app->getExtensionRoot() . 'xuan/im/apischeme.json'#g" zentaoxx/extension/xuan/im/model.php
+ sed -i "/getModuleExtPath(/ r tools/fixxuan" zentaoxx/framework/xuanxuan.class.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/en2de.php zentaoxx/tools; cd zentaoxx/tools; php en2de.php ../
@@ -242,12 +244,10 @@ ci:
make package
zip -rq -9 ZenTaoPMS.$(VERSION).zip zentaopms
- #make deb; make rpm; make en
rm -fr zentaopms zentaoxx zentaoxx.*.zip
make en
rm -fr zentaopms zentaoxx zentaoxx.*.zip
php tools/mergezentaopms.php $(VERSION)
- rm zentaobiz*.zip zentaomax*.zip
+ rm -f zentaobiz*.zip zentaomax*.zip $(BUILD_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm
cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH)
- rm -f $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm
mv *.zip *.deb *.rpm $(RELEASE_PATH)
diff --git a/config/filter.php b/config/filter.php
index 7cf1e28852..d8732044d1 100644
--- a/config/filter.php
+++ b/config/filter.php
@@ -246,6 +246,7 @@ $filter->program->ajaxgetdropmenu->cookie['showClosed'] = 'code';
$filter->project->default->cookie['lastProject'] = 'int';
$filter->project->default->cookie['lastPRJ'] = 'int';
$filter->project->default->cookie['projectMode'] = 'code';
+$filter->project->default->cookie['kanbanview'] = 'code';
$filter->project->browse->cookie['involved'] = 'code';
$filter->project->browse->cookie['projectType'] = 'code';
$filter->project->story->cookie['storyModuleParam'] = 'int';
diff --git a/db/update11.7.sql b/db/update11.7.sql
index f177f5c124..fbf0f9b24f 100644
--- a/db/update11.7.sql
+++ b/db/update11.7.sql
@@ -68,3 +68,4 @@ ALTER TABLE `zt_bug` ADD `entry` varchar(255) COLLATE 'utf8_general_ci' NOT NULL
ALTER TABLE `zt_repobranch` ADD INDEX `revision` (`revision`);
DELETE FROM `zt_grouppriv` WHERE `module` = 'api' AND `method` = 'sql';
+REPLACE INTO `zt_config` set `owner` = 'system', `module` = 'common', `section` = 'global', `key` = 'showAnnual', `value` = '1';
diff --git a/db/update16.4.sql b/db/update16.4.sql
index d87b04cf5d..c874b5ea6b 100644
--- a/db/update16.4.sql
+++ b/db/update16.4.sql
@@ -29,3 +29,5 @@ INSERT INTO `zt_group` (`vision`, `name`, `role`, `desc`) VALUES
('lite', '迅捷版用户分组', 'liteUser', '迅捷版用户分组');
ALTER TABLE `zt_productplan` ADD `closedReason` varchar(20) NOT NULL AFTER `order`;
+
+update zt_config set `value` = concat(`value`, ',visions') where module = 'user' and `key` = 'requiredFields' and section in ('create', 'edit');
diff --git a/extension/lite/execution/ext/control/kanban.php b/extension/lite/execution/ext/control/kanban.php
index 69571b03f5..a368309fdf 100644
--- a/extension/lite/execution/ext/control/kanban.php
+++ b/extension/lite/execution/ext/control/kanban.php
@@ -12,6 +12,9 @@ class myExecution extends execution
$this->loadModel('project')->setMenu($execution->project);
$this->lang->kanban->menu->execution['subMenu'] = new stdClass();
+ $this->session->set('kanbanview', $currentMethod);
+ setcookie('kanbanview', $currentMethod, $this->config->cookieLife, $this->config->webRoot, '', false, true);
+
/* change subMenu to sub select menu */
$TRActions = $this->execution->getTRActions($currentMethod);
diff --git a/extension/lite/execution/ext/model/lite.php b/extension/lite/execution/ext/model/lite.php
index 533fd32350..2930759820 100644
--- a/extension/lite/execution/ext/model/lite.php
+++ b/extension/lite/execution/ext/model/lite.php
@@ -29,8 +29,18 @@ public function setMenu($executionID, $buildID = 0, $extra = '')
}
$modulePageNav .= "";
- if(in_array($this->app->rawMethod, array('task', 'calendar', 'gantt', 'tree', 'grouptask'))) $this->lang->TRActions = $this->getTRActions($this->app->rawMethod);
- if(in_array($this->app->rawMethod, array('relation', 'maintainrelation'))) $this->lang->TRActions = $this->getTRActions('gantt');
+ $lowerModule = strtolower($this->app->rawModule);
+ $lowerMethod = strtolower($this->app->rawMethod);
+
+ if($lowerModule == 'execution' and strpos('|kanban|task|calendar|gantt|tree|grouptask|', "|{$lowerMethod}|") !== false)
+ {
+ $this->session->set('kanbanview', $lowerMethod);
+ setcookie('kanbanview', $lowerMethod, $this->config->cookieLife, $this->config->webRoot, '', false, true);
+ }
+
+ if(strpos('|task|calendar|gantt|tree|grouptask|', "|{$lowerMethod}|") !== false) $this->lang->TRActions = $this->getTRActions($lowerMethod);
+ if(strpos('|relation|maintainrelation|', "|{$lowerMethod}|") !== false) $this->lang->TRActions = $this->getTRActions('gantt');
+ if($lowerModule == 'task' || ($lowerModule == 'execution' and strpos('|kanban|task|calendar|gantt|tree|grouptask|', "|{$lowerMethod}|") === false)) $this->lang->TRActions = $this->getTRActions($this->session->kanbanview);
$this->lang->modulePageNav = $modulePageNav;
}
@@ -94,12 +104,14 @@ public function getTRActions($currentMethod)
}
$TRActions = '';
- $TRActions .= "
";
- $TRActions .= html::a('javascript:;', "
" . $subMenu->{$currentMethod}['name'] . "
", '', "data-toggle='dropdown' class='btn btn-link'");
+ $TRActions .= "
";
+ $TRActions .= html::a(helper::createLink('execution', $subMenu->{$currentMethod}['method'], $subMenu->{$currentMethod}['vars']), " " . $subMenu->{$currentMethod}['name'], '', "class='btn btn-link'");
+ $TRActions .= "";
$TRActions .= "
";
diff --git a/extension/lite/group/ext/lang/en/lite.php b/extension/lite/group/ext/lang/en/lite.php
index 71b1dad82e..58d3cdaab8 100644
--- a/extension/lite/group/ext/lang/en/lite.php
+++ b/extension/lite/group/ext/lang/en/lite.php
@@ -1,2 +1,11 @@
config->edition != 'open')
+{
+ $lang->resource->company->todo = 'companyTodo';
+ $lang->resource->company->calendar = 'effortCalendar';
+ $lang->resource->company->allTodo = 'allTodo';
+ $lang->resource->company->effort = 'companyEffort';
+ $lang->resource->company->alleffort = 'allEffort';
+}
\ No newline at end of file
diff --git a/extension/lite/group/ext/lang/zh-cn/lite.php b/extension/lite/group/ext/lang/zh-cn/lite.php
index 71b1dad82e..58d3cdaab8 100644
--- a/extension/lite/group/ext/lang/zh-cn/lite.php
+++ b/extension/lite/group/ext/lang/zh-cn/lite.php
@@ -1,2 +1,11 @@
config->edition != 'open')
+{
+ $lang->resource->company->todo = 'companyTodo';
+ $lang->resource->company->calendar = 'effortCalendar';
+ $lang->resource->company->allTodo = 'allTodo';
+ $lang->resource->company->effort = 'companyEffort';
+ $lang->resource->company->alleffort = 'allEffort';
+}
\ No newline at end of file
diff --git a/extension/lite/project/ext/view/execution.html.php b/extension/lite/project/ext/view/execution.html.php
index 55afe463e1..3040070ec9 100644
--- a/extension/lite/project/ext/view/execution.html.php
+++ b/extension/lite/project/ext/view/execution.html.php
@@ -38,7 +38,7 @@
$kanban):?>
-
id");?>'>
+
cookie->kanbanview ? $this->cookie->kanbanview : 'kanban', "kanbanID=$kanban->id");?>'>
execution->statusList, $kanban->status);?>
diff --git a/extension/lite/task/ext/view/create.html.php b/extension/lite/task/ext/view/create.html.php
index 6583ef2260..a3fb48075c 100644
--- a/extension/lite/task/ext/view/create.html.php
+++ b/extension/lite/task/ext/view/create.html.php
@@ -95,7 +95,7 @@
| task->story;?> |
- task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->id"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?>
+ task->noticeLinkStory, html::a($this->createLink('execution', 'linkStory', "executionID=$execution->project"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?>
story => empty($stories) ? '': $stories[$task->story]), $task->story, "class='form-control chosen' onchange='setStoryRelated();'");?>
preview;?>
diff --git a/lib/scm/gitlab.class.php b/lib/scm/gitlab.class.php
index e5645e816c..1d702b267b 100644
--- a/lib/scm/gitlab.class.php
+++ b/lib/scm/gitlab.class.php
@@ -646,7 +646,7 @@ class gitlab
$param = new stdclass();
$param->path = urldecode($path);
- $param->ref_name = $fromRevision ? $fromRevision : $this->branch;
+ $param->ref_name = ($toRevision != 'HEAD' and $toRevision) ? $toRevision : $this->branch;
$fromDate = $this->getCommittedDate($fromRevision);
$toDate = $this->getCommittedDate($toRevision);
diff --git a/module/bug/control.php b/module/bug/control.php
index 76f9ee2e47..77185c8bad 100644
--- a/module/bug/control.php
+++ b/module/bug/control.php
@@ -2236,15 +2236,17 @@ class bug extends control
* Ajax get project team members.
*
* @param int $projectID
+ * @param string $$selectedUser
* @access public
- * @return void
+ * @return string
*/
- public function ajaxGetProjectTeamMembers($projectID)
+ public function ajaxGetProjectTeamMembers($projectID, $selectedUser = '')
{
$users = $this->loadModel('user')->getPairs('noclosed');
$teamMembers = empty($projectID) ? array() : $this->loadModel('project')->getTeamMemberPairs($projectID);
foreach($teamMembers as $account => $member) $teamMembers[$account] = $users[$account];
- return print(html::select('assignedTo', $teamMembers, '', 'class="form-control"'));
+
+ return print(html::select('assignedTo', $teamMembers, $selectedUser, 'class="form-control"'));
}
diff --git a/module/bug/js/common.js b/module/bug/js/common.js
index 9b4b38b923..39a5065509 100644
--- a/module/bug/js/common.js
+++ b/module/bug/js/common.js
@@ -29,11 +29,7 @@ $(function()
*/
function loadAll(productID)
{
- if(page == 'create')
- {
- loadExecutionTeamMembers(productID);
- setAssignedTo();
- }
+ if(page == 'create') loadExecutionTeamMembers(productID, true);
if(typeof(changeProductConfirmed) != 'undefined' && !changeProductConfirmed)
{
@@ -485,7 +481,7 @@ function loadExecutionBuilds(executionID)
*/
function loadProjectTeamMembers(projectID)
{
- link = createLink('bug', 'ajaxGetProjectTeamMembers', 'projectID=' + projectID);
+ link = createLink('bug', 'ajaxGetProjectTeamMembers', 'projectID=' + projectID + '&selectedUser=' + $('#assignedTo').val());
$.get(link, function(data)
{
if(!data) data = ' ';
diff --git a/module/bug/js/create.js b/module/bug/js/create.js
index 710b877545..1b381ac281 100644
--- a/module/bug/js/create.js
+++ b/module/bug/js/create.js
@@ -25,10 +25,11 @@ function loadAllUsers()
* Load team members of the latest execution of a product as assignedTo list.
*
* @param int $productID
+ * @param bool $changeProduct
* @access public
* @return void
*/
-function loadExecutionTeamMembers(productID)
+function loadExecutionTeamMembers(productID, changeProduct)
{
var link = createLink('bug', 'ajaxLoadExecutionTeamMembers', 'productID=' + productID + '&selectedUser=' + $('#assignedTo').val());
$.post(link, function(data)
@@ -36,6 +37,7 @@ function loadExecutionTeamMembers(productID)
$('#assignedTo').replaceWith(data);
$('#assignedTo_chosen').remove();
$('#assignedTo').chosen();
+ if(typeof(changeProduct) != undefined && changeProduct) setAssignedTo();
})
}
diff --git a/module/bug/view/create.html.php b/module/bug/view/create.html.php
index c33c1a9f2a..ca57e65f41 100644
--- a/module/bug/view/create.html.php
+++ b/module/bug/view/create.html.php
@@ -124,7 +124,9 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
|
diff --git a/module/common/model.php b/module/common/model.php
index f3ccab9128..443cc5c95d 100644
--- a/module/common/model.php
+++ b/module/common/model.php
@@ -2205,6 +2205,8 @@ EOD;
if(isset($this->app->user))
{
+ if(in_array($module, $this->config->programPriv->waterfall) and $this->app->tab == 'project') return true;
+
$this->app->user = $this->session->user;
if(!commonModel::hasPriv($module, $method)) $this->deny($module, $method);
}
diff --git a/module/custom/control.php b/module/custom/control.php
index 909153542d..dc159ba0c6 100644
--- a/module/custom/control.php
+++ b/module/custom/control.php
@@ -163,7 +163,7 @@ class custom extends control
foreach($_POST['keys'] as $index => $key)
{
if(!empty($key)) $key = trim($key);
- /* Invalid key. It should be numbers. (It includes severityList in bug module and priList in stroy, task, bug, testcasea, testtask and todo module.) */
+ /* Invalid key. It should be numbers. (It includes severityList in bug module and priList in story, task, bug, testcasea, testtask and todo module.) */
if($field == 'priList' or $field == 'severityList')
{
if(!is_numeric($key) or $key > 255) return $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->invalidNumberKey));
diff --git a/module/custom/model.php b/module/custom/model.php
index 2576344129..15dc1f03d2 100644
--- a/module/custom/model.php
+++ b/module/custom/model.php
@@ -244,6 +244,18 @@ class customModel extends model
$link = explode('|', $link);
list($label, $module, $method) = $link;
$hasPriv = commonModel::hasPriv($module, $method);
+ /* Fix bug #20464 */
+ if(!$hasPriv and is_array($item) and isset($item['subMenu']))
+ {
+ foreach($item['subMenu'] as $subMenu)
+ {
+ if(!isset($subMenu['link'])) continue;
+ list($subLabel, $module, $method) = explode('|', $subMenu['link']);
+ $hasPriv = commonModel::hasPriv($module, $method);
+ if($hasPriv) break;
+ }
+ }
+
if($module == 'execution' and $method == 'more') $hasPriv = true;
if($module == 'project' and $method == 'other') $hasPriv = true;
}
diff --git a/module/design/control.php b/module/design/control.php
index d783517a56..f68abb68d9 100644
--- a/module/design/control.php
+++ b/module/design/control.php
@@ -84,18 +84,27 @@ class design extends control
$this->lang->TRActions .= html::a($this->createLink('design', 'submit', "productID=$productID", '', true), " {$this->lang->design->submit}", '', "class='btn btn-secondary iframe'");
$this->lang->TRActions .= '';
}
- $this->lang->TRActions .= '';
- $this->lang->TRActions .= html::a(inlink('create', "projectID=$projectID&productID=$productID&type=$type"), " {$this->lang->design->create}", '', "class='btn btn-primary'");
- $this->lang->TRActions .= "';
- $this->lang->TRActions .= "
';
+ if(common::hasPriv('design', 'create')) $this->lang->TRActions .= '' . html::a($this->createLink('design', 'create', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->create, '', "class='btn btn-link'") . '';
+ if(common::hasPriv('design', 'batchCreate')) $this->lang->TRActions .= '' . html::a($this->createLink('design', 'batchCreate', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->batchCreate, '', "class='btn btn-link'") . '';
+
+ $this->lang->TRActions .= '';
+ $this->lang->TRActions .= '';
+ $this->lang->TRActions .= '';
+ }
+ else
+ {
+ if(common::hasPriv('design', 'create')) $this->lang->TRActions .= html::a(inlink('create', "projectID=$projectID&productID=$productID&type=$type"), " {$this->lang->design->create}", '', "class='btn btn-primary'");
+ if(common::hasPriv('design', 'batchCreate')) $this->lang->TRActions .= html::a(inlink('batchCreate', "projectID=$projectID&productID=$productID&type=$type"), " {$this->lang->design->batchCreate}", '', "class='btn btn-primary'");
+ }
/* Init pager and get designs. */
$this->app->loadClass('pager', $static = true);
diff --git a/module/design/view/browse.html.php b/module/design/view/browse.html.php
index 5fb8fc535d..d080b42d5c 100644
--- a/module/design/view/browse.html.php
+++ b/module/design/view/browse.html.php
@@ -44,7 +44,7 @@
| id);?> |
design->typeList, $design->type);?> |
- createLink('design', 'view', "id={$design->id}"), $design->name);?> |
+ createLink('design', 'view', "id={$design->id}"), $design->name) : $design->name;?> |
createdBy);?> |
createdDate, 0, 11);?> |
design->printAssignedHtml($design, $users);?> |
diff --git a/module/execution/css/all.en.css b/module/execution/css/all.en.css
index 1eb9de2ae7..885a0e066f 100644
--- a/module/execution/css/all.en.css
+++ b/module/execution/css/all.en.css
@@ -1 +1,2 @@
.thWidth {width: 130px !important;}
+td.flex span.project-type-label {min-width: 60px;}
diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js
index d39357a3bc..9350f13cd2 100644
--- a/module/execution/js/kanban.js
+++ b/module/execution/js/kanban.js
@@ -792,6 +792,7 @@ function handleDropTask($element, event, kanban)
var newLane = $newCol.closest('.kanban-lane').data('lane');
var cardType = $card.find('.kanban-card').data('type');
+ if(!oldCol || !newCol || !newLane || !oldLane) return false;
if(oldCol.id === newCol.id && newLane.id === oldLane.id) return false;
var cardID = $card.data().id;
diff --git a/module/execution/js/taskkanban.js b/module/execution/js/taskkanban.js
index d10800f92b..c03748f81b 100644
--- a/module/execution/js/taskkanban.js
+++ b/module/execution/js/taskkanban.js
@@ -73,7 +73,7 @@ function renderDeadline(deadline)
function renderStoryItem(item, $item, col)
{
var scaleSize = window.kanbanScaleSize;
- if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
+ if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if(scaleSize <= 3)
{
@@ -135,7 +135,7 @@ function renderStoryItem(item, $item, col)
function renderBugItem(item, $item, col)
{
var scaleSize = window.kanbanScaleSize;
- if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
+ if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if(scaleSize <= 3)
{
@@ -199,7 +199,7 @@ function renderBugItem(item, $item, col)
function renderTaskItem(item, $item, col)
{
var scaleSize = window.kanbanScaleSize;
- if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
+ if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize);
if(scaleSize <= 3)
{
@@ -298,6 +298,8 @@ function renderColumnCount($count, count, col)
function renderHeaderCol($col, col, $header, kanban)
{
if(col.asParent) $col = $col.children('.kanban-header-col');
+ if($col.children('.actions').context != undefined) return;
+
var $actions = $('');
var printStoryButton = printTaskButton = printBugButton = false;
if(priv.canCreateStory || priv.canBatchCreateStory || priv.canLinkStory || priv.canLinkStoryByPlan) printStoryButton = true;
@@ -717,6 +719,7 @@ function handleDropTask($element, event, kanban)
var newLane = $newCol.closest('.kanban-lane').data('lane');
var cardType = $card.find('.kanban-card').data('type');
+ if(!oldCol || !newCol || !newLane || !oldLane) return false;
if(oldCol.id === newCol.id && newLane.id === oldLane.id) return false;
var cardID = $card.data().id;
@@ -796,7 +799,7 @@ function createColumnCreateMenu(options)
if(col.laneType == 'story')
{
if(priv.canCreateStory) items.push({label: storyLang.create, url: $.createLink('story', 'create', 'productID=' + productID, '', true), className: 'iframe'});
- if(priv.canBatchCreateStory) items.push({label: executionLang.batchCreateStroy, url: $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
+ if(priv.canBatchCreateStory) items.push({label: executionLang.batchCreateStory, url: $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
if(priv.canLinkStory) items.push({label: executionLang.linkStory, url: $.createLink('execution', 'linkStory', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
if(priv.canLinkStoryByPlan) items.push({label: executionLang.linkStoryByPlan, url: '#linkStoryByPlan', 'attrs' : {'data-toggle': 'modal'}});
}
diff --git a/module/install/control.php b/module/install/control.php
index f4e411121d..5bf3ceac35 100644
--- a/module/install/control.php
+++ b/module/install/control.php
@@ -206,11 +206,13 @@ class install extends control
if($this->post->importDemoData) $this->install->importDemoData();
if(dao::isError()) echo js::alert($this->lang->install->errorImportDemoData);
- $this->loadModel('setting')->updateVersion($this->config->version);
- $this->loadModel('setting')->setItem('system.common.global.flow', $this->post->flow);
- $this->loadModel('setting')->setItem('system.common.safe.mode', '1');
- $this->loadModel('setting')->setItem('system.common.safe.changeWeak', '1');
- $this->loadModel('setting')->setItem('system.common.global.cron', 1);
+ $this->loadModel('setting');
+ $this->setting->updateVersion($this->config->version);
+ $this->setting->setSN();
+ $this->setting->setItem('system.common.global.flow', $this->post->flow);
+ $this->setting->setItem('system.common.safe.mode', '1');
+ $this->setting->setItem('system.common.safe.changeWeak', '1');
+ $this->setting->setItem('system.common.global.cron', 1);
if(strpos($this->app->getClientLang(), 'zh') === 0) $this->loadModel('api')->createDemoData($this->lang->api->zentaoAPI, 'http://' . $_SERVER['HTTP_HOST'] . $this->app->config->webRoot . 'api.php/v1', '16.0');
return print(js::locate(inlink('step6'), 'parent'));
diff --git a/module/kanban/js/view.js b/module/kanban/js/view.js
index bf5a191c4e..b400a88a37 100644
--- a/module/kanban/js/view.js
+++ b/module/kanban/js/view.js
@@ -976,6 +976,7 @@ function handleDropTask($element, event, kanban)
var regionID = $card.closest('.region').data('id');
var kanbanID = $card.closest('#kanban').data('id');
+ if(!oldCol || !newCol || !newLane || !oldLane) return false;
if(oldCol.id === newCol.id && newLane.id === oldLane.id) return false;
var cardID = $card.data().id;
@@ -1183,7 +1184,7 @@ function createColumnCreateMenu(options)
var laneID = col.$kanbanData.lanes[0].id ? col.$kanbanData.lanes[0].id : 0;
var columnID = col.id;
- if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal'}});
+ if(privs.includes('createCard')) items.push({label: kanbanLang.createCard, url: $.createLink('kanban', 'createCard', 'kanbanID=' + kanbanID + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID, '', true), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('batchCreateCard')) items.push({label: kanbanLang.batchCreateCard, url: $.createLink('kanban', 'batchCreateCard', 'kanbanID=' + kanbanID + '®ionID=' + regionID + '&groupID=' + groupID + '&laneID=' + laneID + '&columnID=' + columnID), attrs: {'data-width': '80%'}});
if(privs.includes('import') && kanban.object.indexOf('cards') != -1) items.push({label: kanbanLang.importCard, url: $.createLink('kanban', 'importCard', 'kanbanID=' + kanbanID + '®ionID=' + regionID + '&groupID=' + groupID + '&columnID=' + columnID), className: 'iframe', attrs: {'data-toggle': 'modal'}});
if(privs.includes('import') && kanban.object && kanban.object != 'cards') items.push({className: 'parentDivider'});
diff --git a/module/kanban/model.php b/module/kanban/model.php
index a9ffd90ade..0dc172b298 100644
--- a/module/kanban/model.php
+++ b/module/kanban/model.php
@@ -1419,7 +1419,7 @@ class kanbanModel extends model
$lanes = $this->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
if(empty($lanes)) return array();
- $columns = $this->dao->select('t1.*, t2.`type` as columnType, t2.limit, t2.name as columnName')->from(TABLE_KANBANCELL)->alias('t1')
+ $columns = $this->dao->select('t1.*, t2.`type` as columnType, t2.limit, t2.name as columnName, t2.color')->from(TABLE_KANBANCELL)->alias('t1')
->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.`column` = t2.id')
->where('t1.kanban')->eq($executionID)
->andWhere('t1.`type`')->eq($browseType)
@@ -1460,7 +1460,7 @@ class kanbanModel extends model
$columnData[$column->column]['id'] = $column->column;
$columnData[$column->column]['type'] = $column->columnType;
$columnData[$column->column]['name'] = $column->columnName;
- $columnData[$column->column]['color'] = '#333';
+ $columnData[$column->column]['color'] = $column->color;
$columnData[$column->column]['limit'] = $column->limit;
$columnData[$column->column]['laneType'] = $browseType;
$columnData[$column->column]['asParent'] = in_array($column->columnType, array('develop', 'test', 'resolving')) ? true : false;
diff --git a/module/my/control.php b/module/my/control.php
index 95d130dc23..92be67f2b1 100644
--- a/module/my/control.php
+++ b/module/my/control.php
@@ -499,7 +499,7 @@ EOF;
$this->view->position[] = $this->lang->my->bug;
$this->view->bugs = $bugs;
$this->view->users = $this->user->getPairs('noletter');
- $this->view->memberPairs = $this->user->getPairs('noletter|nodeleted');
+ $this->view->memberPairs = $this->user->getPairs('noletter|nodeleted|noclosed');
$this->view->tabID = 'bug';
$this->view->type = $type;
$this->view->recTotal = $recTotal;
diff --git a/module/my/view/buildcontactlists.html.php b/module/my/view/buildcontactlists.html.php
index 4500d2b2bd..1a210b3245 100644
--- a/module/my/view/buildcontactlists.html.php
+++ b/module/my/view/buildcontactlists.html.php
@@ -17,8 +17,9 @@ if($contactLists)
}
else
{
+ $width = isonlybody() ? 'data-width=100%' : '';
echo '';
- echo '";
+ echo '";
echo '';
echo '';
echo '';
diff --git a/module/my/view/profile.html.php b/module/my/view/profile.html.php
index d36fd514be..33e9c60d5a 100644
--- a/module/my/view/profile.html.php
+++ b/module/my/view/profile.html.php
@@ -20,7 +20,7 @@
realname;?>
diff --git a/module/projectstory/control.php b/module/projectstory/control.php
index 4f5db62636..2907121fc4 100644
--- a/module/projectstory/control.php
+++ b/module/projectstory/control.php
@@ -110,7 +110,7 @@ class projectStory extends control
* Batch unlink story.
*
* @param int $projectID
- * @param string $stroyIdList
+ * @param string $storyIdList
* @access public
* @return string
*/
diff --git a/module/score/control.php b/module/score/control.php
index 62c190e715..d6648c4c25 100644
--- a/module/score/control.php
+++ b/module/score/control.php
@@ -31,8 +31,6 @@ class score extends control
*/
public function rule()
{
- $this->loadModel('my')->setMenu();
-
$this->view->title = $this->lang->my->scoreRule;
$this->view->position[] = $this->lang->my->scoreRule;
$this->display();
diff --git a/module/story/control.php b/module/story/control.php
index 814e3a8ca2..43e60d13f4 100644
--- a/module/story/control.php
+++ b/module/story/control.php
@@ -1101,8 +1101,6 @@ class story extends control
/* Set the menu. */
$from = $this->app->tab;
- $this->product->setMenu($story->product, $story->branch);
-
if($from == 'execution')
{
$this->execution->setMenu($param);
@@ -1116,6 +1114,10 @@ class story extends control
$products = $this->product->getProductPairsByProject(0, 'noclosed');
$this->loadModel('qa')->setMenu($products, $story->product);
}
+ else
+ {
+ $this->product->setMenu($story->product, $story->branch);
+ }
$reviewers = $this->story->getReviewerPairs($storyID, $story->version);
$checkSuperReviewed = strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . trim($story->reviewedBy, ',') . ',');
@@ -1468,7 +1470,6 @@ class story extends control
{
$this->lang->story->menu = $this->lang->my->menu;
$this->lang->story->menuOrder = $this->lang->my->menuOrder;
- $this->loadModel('my')->setMenu();
if($from == 'work') $this->lang->my->menu->work['subModule'] = 'story';
if($from == 'contribute') $this->lang->my->menu->contribute['subModule'] = 'story';
@@ -1988,20 +1989,23 @@ class story extends control
*
* @param int $executionID
* @param int $productID
+ * @param int $branch
+ * @param int $moduleID
* @param int $storyID
* @param string $number
- * @param string $type
+ * @param string $type full
+ * @param string $status all|unclosed
* @access public
* @return void
*/
- public function ajaxGetExecutionStories($executionID, $productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $number = '', $type= 'full')
+ public function ajaxGetExecutionStories($executionID, $productID = 0, $branch = 0, $moduleID = 0, $storyID = 0, $number = '', $type = 'full', $status = 'all')
{
if($moduleID)
{
$moduleID = $this->loadModel('tree')->getStoryModule($moduleID);
$moduleID = $this->tree->getAllChildID($moduleID);
}
- $stories = $this->story->getExecutionStoryPairs($executionID, $productID, $branch, $moduleID, $type);
+ $stories = $this->story->getExecutionStoryPairs($executionID, $productID, $branch, $moduleID, $type, $status);
if($this->app->getViewType() === 'json')
{
return print(json_encode($stories));
diff --git a/module/story/model.php b/module/story/model.php
index bd97909090..ced0c50d4e 100644
--- a/module/story/model.php
+++ b/module/story/model.php
@@ -647,9 +647,9 @@ class storyModel extends model
$story = fixer::input('post')->stripTags($this->config->story->editor->change['id'], $this->config->allowedTags)->get();
- $oldStroyReviewers = $this->getReviewerPairs($storyID, $oldStory->version);
+ $oldStoryReviewers = $this->getReviewerPairs($storyID, $oldStory->version);
$_POST['reviewer'] = isset($_POST['reviewer']) ? $_POST['reviewer'] : array();
- $reviewerHasChanged = (array_diff(array_keys($oldStroyReviewers), $_POST['reviewer']) or array_diff($_POST['reviewer'], array_keys($oldStroyReviewers)));
+ $reviewerHasChanged = (array_diff(array_keys($oldStoryReviewers), $_POST['reviewer']) or array_diff($_POST['reviewer'], array_keys($oldStoryReviewers)));
if($story->spec != $oldStory->spec or $story->verify != $oldStory->verify or $story->title != $oldStory->title or $this->loadModel('file')->getCount() or $reviewerHasChanged) $specChanged = true;
$now = helper::now();
@@ -3925,7 +3925,7 @@ class storyModel extends model
}
if($storyType == 'requirement') echo 'SR ';
if($story->parent > 0 and isset($story->parentName)) $story->title = "{$story->parentName} / {$story->title}";
- if(isset($branches[$story->branch]) and $showBranch) echo "{$branches[$story->branch]} ";
+ if(isset($branches[$story->branch]) and $showBranch and $this->config->vision == 'rnd') echo "{$branches[$story->branch]} ";
if($story->module and isset($modulePairs[$story->module])) echo "{$modulePairs[$story->module]} ";
if($story->parent > 0) echo '' . $this->lang->story->childrenAB . ' ';
echo $canView ? html::a($storyLink, $story->title, '', "style='color: $story->color' data-app='$tab'") : "{$story->title}";
diff --git a/module/story/view/batchedit.html.php b/module/story/view/batchedit.html.php
index 10f90a4e11..069f8d94bb 100644
--- a/module/story/view/batchedit.html.php
+++ b/module/story/view/batchedit.html.php
@@ -148,7 +148,7 @@ foreach(explode(',', $showFields) as $field)
|
- app->tab == 'product' ? html::a($this->session->storyList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?>
+ app->tab == 'product' or $this->app->tab == 'execution') ? html::a($this->session->storyList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?>
|
diff --git a/module/task/js/create.js b/module/task/js/create.js
index 691e4817e5..4afe1f03e8 100644
--- a/module/task/js/create.js
+++ b/module/task/js/create.js
@@ -273,7 +273,7 @@ function loadModuleRelated()
/* Get select of stories.*/
function setStories(moduleID, executionID)
{
- link = createLink('story', 'ajaxGetExecutionStories', 'executionID=' + executionID + '&productID=0&branch=all&moduleID=' + moduleID);
+ link = createLink('story', 'ajaxGetExecutionStories', 'executionID=' + executionID + '&productID=0&branch=all&moduleID=' + moduleID + '&storyID=0&number=&type=full&status=unclosed');
$.get(link, function(stories)
{
var storyID = $('#story').val();
diff --git a/module/task/model.php b/module/task/model.php
index 0b8830b143..cf3bbee362 100644
--- a/module/task/model.php
+++ b/module/task/model.php
@@ -2171,7 +2171,7 @@ class taskModel extends model
$task->parentName = $parent->name;
}
}
- }
+ }
return $this->processTasks($tasks);
}
diff --git a/module/todo/control.php b/module/todo/control.php
index 737bc58f70..902196ed9a 100644
--- a/module/todo/control.php
+++ b/module/todo/control.php
@@ -23,7 +23,6 @@ class todo extends control
$this->app->loadClass('date');
$this->loadModel('task');
$this->loadModel('bug');
- $this->loadModel('my')->setMenu();
}
/**
diff --git a/module/tree/view/browse.html.php b/module/tree/view/browse.html.php
index 9cf64ae901..99a9876b90 100644
--- a/module/tree/view/browse.html.php
+++ b/module/tree/view/browse.html.php
@@ -221,7 +221,7 @@ $(function()
},
itemCreator: function($li, item)
{
- var link = (item.id !== undefined && item.type != 'line') ? ('' + item.name + '') : ('' + item.name + '');
+ var link = (item.id !== undefined && item.type != 'line') ? ('' + item.name + '') : ('' + item.name + '');
var $toggle = $('' + link + '');
if(item.type === 'bug') $toggle.append(' [B]');
if(item.type === 'case') $toggle.append(' [C]');
diff --git a/module/upgrade/control.php b/module/upgrade/control.php
index bcada683c5..30ac76ae51 100644
--- a/module/upgrade/control.php
+++ b/module/upgrade/control.php
@@ -721,7 +721,7 @@ class upgrade extends control
$this->view->title = $this->lang->upgrade->result;
$this->view->position[] = $this->lang->upgrade->common;
- $needProcess = $this->upgrade->checkProcess($fromVersion);
+ $needProcess = $this->upgrade->checkProcess();
$this->view->needProcess = $needProcess;
$this->view->fromVersion = $fromVersion;
$this->display();
diff --git a/module/upgrade/lang/en.php b/module/upgrade/lang/en.php
index 854467003b..b323b58758 100644
--- a/module/upgrade/lang/en.php
+++ b/module/upgrade/lang/en.php
@@ -27,7 +27,7 @@ $lang->upgrade->warnningContent = << mysqldump -u username -p dbname > filename
Change the red text into corresponding Username and Database name.
- e.g. mysqldump -u root -p zentao >zentao.bak
+ e.g. mysqldump -u root -p zentao > zentao.bak
EOT;
diff --git a/module/upgrade/lang/zh-cn.php b/module/upgrade/lang/zh-cn.php
index d989fe0ebe..e5d20116a4 100644
--- a/module/upgrade/lang/zh-cn.php
+++ b/module/upgrade/lang/zh-cn.php
@@ -27,7 +27,7 @@ $lang->upgrade->warnningContent = << mysqldump -u username -p dbname > filename
要将上面红色的部分分别替换成对应的用户名和禅道系统的数据库名。
- 比如: mysqldump -u root -p zentao >zentao.bak
+ 比如: mysqldump -u root -p zentao > zentao.bak
EOT;
diff --git a/module/upgrade/model.php b/module/upgrade/model.php
index f17ea6990f..93f8983867 100644
--- a/module/upgrade/model.php
+++ b/module/upgrade/model.php
@@ -27,6 +27,49 @@ class upgradeModel extends model
$this->loadModel('setting');
}
+ /**
+ * Get versions to update
+ *
+ * @param mixed $openVersion
+ * @access public
+ * @return array
+ */
+ public function getVersionsToUpdate($openVersion, $fromEdition)
+ {
+ $versions = array();
+
+ /* Always update open. */
+ foreach($this->lang->upgrade->fromVersions as $version => $versionName)
+ {
+ if(!is_numeric($version[0])) continue;
+ if(version_compare(str_replace('_', '.', $version), str_replace('_', '.', $openVersion)) < 0) continue;
+ $versions[$version] = array('pro' => array(), 'biz' => array(), 'max' => array());
+ }
+ if($fromEdition == 'open') return $versions;
+
+ /* Update to pro|biz|max. */
+ foreach($this->config->upgrade->proVersion as $pro => $open)
+ {
+ if(isset($versions[$open])) $versions[$open]['pro'][] = $pro;
+ }
+ if($fromEdition == 'pro') return $versions;
+
+ /* Update to biz|max. */
+ foreach($this->config->upgrade->bizVersion as $biz => $open)
+ {
+ if(isset($versions[$open])) $versions[$open]['biz'][] = $biz;
+ }
+ if($fromEdition == 'biz') return $versions;
+
+ /* Update to max. */
+ foreach($this->config->upgrade->maxVersion as $max => $open)
+ {
+ if(isset($versions[$open])) $versions[$open]['max'][] = $max;
+ }
+
+ return $versions;
+ }
+
/**
* The execute method. According to the $fromVersion call related methods.
*
@@ -38,81 +81,60 @@ class upgradeModel extends model
{
set_time_limit(0);
- $editions = array('p' => 'proVersion', 'b' => 'bizVersion', 'm' => 'maxVersion');
+ $editions = array('p' => 'pro', 'b' => 'biz', 'm' => 'max');
$fromEdition = is_numeric($fromVersion[0]) ? 'open' : $editions[$fromVersion[0]];
- $openVersion = is_numeric($fromVersion[0]) ? $fromVersion : $this->config->upgrade->{$fromEdition}[$fromVersion];
-
- /* Get versions to be updated. */
- $versions = array();
- $edition = $this->config->edition;
- foreach($this->lang->upgrade->fromVersions as $version => $versionName)
- {
- if(!is_numeric($version[0])) continue;
- if(version_compare(str_replace('_', '.', $version), str_replace('_', '.', $openVersion)) < 0) continue;
- $versions[$version] = array('pro' => array(), 'biz' => array(), 'max' => array());
- }
- foreach($this->config->upgrade->proVersion as $pro => $open)
- {
- if(!isset($versions[$open])) continue;
- if(version_compare(str_replace('_', '.', $openVersion), '16.4', '>=') or $fromEdition == 'pro') $versions[$open]['pro'][] = $pro;
- }
- foreach($this->config->upgrade->bizVersion as $biz => $open)
- {
- if(!isset($versions[$open])) continue;
- if(version_compare(str_replace('_', '.', $openVersion), '16.4', '>=') or $fromEdition == 'biz') $versions[$open]['biz'][] = $biz;
- }
- foreach($this->config->upgrade->maxVersion as $max => $open)
- {
- if(!isset($versions[$open])) continue;
- if(version_compare(str_replace('_', '.', $openVersion), '16.4', '>=') or $fromEdition == 'max') $versions[$open]['max'][] = $max;
- }
/* If the 'current openVersion' is not equal the 'from openVersion', must update structure. */
$currentVersion = str_replace('.', '_', $this->config->version);
- $updateStructure = $openVersion != ($this->config->edition == 'open' ? $currentVersion : $this->config->upgrade->{$this->config->edition . 'Version'}[$currentVersion]);
/* Execute. */
+ $fromOpenVersion = is_numeric($fromVersion[0]) ? $fromVersion : $this->config->upgrade->{$fromEdition . 'Version'}[$fromVersion];
+ $versions = $this->getVersionsToUpdate($fromOpenVersion, $fromEdition);
foreach($versions as $openVersion => $chargedVersions)
{
$executeXuanxuan = false;
- switch($fromEdition)
- {
- case 'open':
- if(str_replace('_', '.', $openVersion) == '10.1') $executeXuanxuan = true;
- $this->saveLogs("Execute $openVersion");
- $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $openVersion)));
- $this->executeOpen($openVersion, $fromVersion, $executeXuanxuan);
- case 'pro':
- foreach($chargedVersions['pro'] as $proVersion)
- {
- $this->saveLogs("Execute $proVersion");
- if($updateStructure) $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $proVersion)));
- if($this->config->edition != 'open') $this->executePro($proVersion);
- }
- case 'biz':
- foreach($chargedVersions['biz'] as $bizVersion)
- {
- $this->saveLogs("Execute $bizVersion");
- if($updateStructure) $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $bizVersion)));
- if($this->config->edition != 'open') $this->executeBiz($bizVersion, $executeXuanxuan);
- }
- case 'max':
- foreach($chargedVersions['max'] as $maxVersion)
- {
- $maxVersion = array_search($openVersion, $this->config->upgrade->maxVersion);
- $this->saveLogs("Execute $maxVersion");
- if($updateStructure) $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $maxVersion)));
- }
+ /* Execute open. */
+ if(str_replace('_', '.', $openVersion) == '10.1') $executeXuanxuan = true;
+
+ $this->saveLogs("Execute $openVersion");
+ $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $openVersion)));
+ $this->executeOpen($openVersion, $fromVersion, $executeXuanxuan);
+
+ /* Execute pro. */
+ foreach($chargedVersions['pro'] as $proVersion)
+ {
+ $this->saveLogs("Execute $proVersion");
+ $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $proVersion)));
+ $this->executePro($proVersion);
+ }
+
+ /* Execute biz. */
+ foreach($chargedVersions['biz'] as $bizVersion)
+ {
+ $this->saveLogs("Execute $bizVersion");
+ $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $bizVersion)));
+ $this->executeBiz($bizVersion, $executeXuanxuan);
+ }
+
+ /* Execute max. */
+ foreach($chargedVersions['max'] as $maxVersion)
+ {
+ $maxVersion = array_search($openVersion, $this->config->upgrade->maxVersion);
+ $this->saveLogs("Execute $maxVersion");
+ $this->execSQL($this->getUpgradeFile(str_replace('_', '.', $maxVersion)));
}
}
- /* Means open source upgrade to biz or max. */
- if($fromEdition == 'open' and $this->config->edition != 'open')
+ /* Means open source/pro upgrade to biz or max. */
+ if($this->config->edition != 'open')
{
- $this->loadModel('effort')->convertEstToEffort();
- $this->importBuildinModules();
- $this->addSubStatus();
+ if($fromEdition == 'open') $this->loadModel('effort')->convertEstToEffort();
+ if($fromEdition == 'open' or $fromEdition == 'pro')
+ {
+ $this->importBuildinModules();
+ $this->addSubStatus();
+ }
}
}
@@ -334,7 +356,6 @@ class upgradeModel extends model
break;
case '11_7':
$this->adjustPriv12_0();
- $this->loadModel('setting')->setItem('system.common.global.showAnnual', '1');
break;
case '12_0_1':
$this->importRepoFromConfig();
@@ -1108,18 +1129,21 @@ class upgradeModel extends model
public function checkConsistency($version = '')
{
if(empty($version)) $version = $this->config->installedVersion;
+
+ $editions = array('p' => 'proVersion', 'b' => 'bizVersion', 'm' => 'maxVersion');
+ $version = str_replace('.', '_', $version);
+ $fromEdition = is_numeric($version[0]) ? 'open' : $editions[$version[0]];
+ $openVersion = is_numeric($version[0]) ? $version : $this->config->upgrade->{$fromEdition}[$version];
+ $openVersion = str_replace('_', '.', $openVersion);
+
$alterSQL = '';
- $standardSQL = $this->app->getAppRoot() . 'db' . DS . 'standard' . DS . 'zentao' . $version . '.sql';
+ $standardSQL = $this->app->getAppRoot() . 'db' . DS . 'standard' . DS . 'zentao' . $openVersion . '.sql';
if(!file_exists($standardSQL)) return $alterSQL;
$lines = file($standardSQL);
if(empty($this->config->isINT))
{
- $xVersion = $version;
- $version = str_replace('.', '_', $version);
- if(strpos($version, 'pro') !== false and isset($this->config->upgrade->proVersion[$version])) $xVersion = str_replace('_', '.', $this->config->upgrade->proVersion[$version]);
- if(strpos($version, 'biz') !== false and isset($this->config->upgrade->bizVersion[$version])) $xVersion = str_replace('_', '.', $this->config->upgrade->bizVersion[$version]);
-
+ $xVersion = $openVersion;
$xStandardSQL = $this->app->getAppRoot() . 'db' . DS . 'standard' . DS . 'xuanxuan' . $xVersion . '.sql';
if(file_exists($xStandardSQL))
{
diff --git a/module/upgrade/view/afterexec.html.php b/module/upgrade/view/afterexec.html.php
index 9da0422326..605f2262ef 100644
--- a/module/upgrade/view/afterexec.html.php
+++ b/module/upgrade/view/afterexec.html.php
@@ -46,6 +46,11 @@