diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 957236940c..0000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "extension/qucheng"]
- path = extension/qucheng
- url = https://gitlab.zcorp.cc/easycorp/qucheng.git
diff --git a/api/v1/entries/testtasks.php b/api/v1/entries/testtasks.php
index 8dcabc1b3d..cc34ac7e28 100644
--- a/api/v1/entries/testtasks.php
+++ b/api/v1/entries/testtasks.php
@@ -24,7 +24,7 @@ class testtasksEntry extends entry
/* Get all testtasks. */
$control = $this->loadController('testtask', 'browse');
- $productID = $this->param('productID', 0);
+ $productID = $this->param('product', 0);
$control->browse($productID, $this->param('branch', ''), ($productID > 0 ? 'local' : 'all') . ',' . $this->param('status', 'totalStatus'), $this->param('order', 'id_desc'), $this->param('total', 0), $this->param('limit', 20), $this->param('page', 1), $this->param('begin', ''), $this->param('end', ''));
$data = $this->getData();
diff --git a/db/endemo.sql b/db/endemo.sql
index 598d75acd9..d2d0550d63 100644
--- a/db/endemo.sql
+++ b/db/endemo.sql
@@ -244,8 +244,8 @@ INSERT INTO `zt_dept` (`id`, `name`, `parent`, `path`, `grade`, `order`, `positi
INSERT INTO `zt_doclib` (`id`, `type`, `product`, `project`, `execution`, `name`, `acl`, `groups`, `users`, `main`, `collector`, `order`, `deleted`) VALUES
(1, 'product', 1, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0'),
(2, 'product', 2, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0'),
-(3, 'project', 0, 0, 1, '项目库', 'default', '', '', '1', '', 0, '0'),
-(4, 'project', 0, 0, 2, '项目库', 'default', '', '', '1', '', 0, '0'),
+(3, 'execution', 0, 0, 1, '项目库', 'default', '', '', '1', '', 0, '0'),
+(4, 'execution', 0, 0, 2, '项目库', 'default', '', '', '1', '', 0, '0'),
(5, 'project', 0, 7, 0, '项目主库', 'default', '', '', '1', '', 0, '0');
INSERT INTO `zt_history` (`id`, `action`, `field`, `old`, `new`, `diff`) VALUES
(1, 14, 'version', '1', '2', ''),
@@ -382,11 +382,11 @@ INSERT INTO `zt_product` (`id`, `program`, `name`, `code`, `bind`, `line`, `type
(2, 6, '企业内部工时管理系统', 'workhourManage', '0', 0, 'normal', 'normal', '', '', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 11:15:20', '5.2.1', 10, '0');
INSERT INTO `zt_productplan` (`id`, `product`, `branch`, `parent`, `title`, `desc`, `begin`, `end`, `order`, `deleted`) VALUES
(1, 1, 0, 0, '1.0版本', '开发出企业网站1.0版本。
', '2020-06-05', '2021-06-04', '', '0');
-INSERT INTO `zt_project` (`id`, `project`, `model`, `type`, `product`, `lifetime`, `budget`, `budgetUnit`, `attribute`, `percent`, `milestone`, `output`, `auth`, `parent`, `path`, `grade`, `name`, `code`, `begin`, `end`, `realBegan`, `realEnd`, `days`, `status`, `subStatus`, `statge`, `pri`, `desc`, `version`, `parentVersion`, `planDuration`, `realDuration`, `openedBy`, `openedDate`, `openedVersion`, `lastEditedBy`, `lastEditedDate`, `closedBy`, `closedDate`, `canceledBy`, `canceledDate`, `PO`, `PM`, `QD`, `RD`, `team`, `acl`, `whitelist`, `order`, `deleted`) VALUES
-(1, 7, '', 'sprint', 'single', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,1,', 1, '企业网站第一期', 'coWeb1', '2020-06-05', '2021-12-04', '0000-00-00', '0000-00-00', 391, 'doing', '', '1', '1', '开发企业网站的基本雏形。
', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 5, '0'),
-(2, 7, '', 'sprint', 'single', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,2,', 1, '企业网站第二期', 'coWebsite2', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 260, 'wait', '', '1', '1', '', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 10, '0'),
-(7, 0, 'scrum', 'project', 'single', 'sprint', '0', 'CNY', '', 0, '0', '', 'extend', 6, ',6,7,', 2, '企业管理系统', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', 'admin', '2021-04-28 11:22:04', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 'projectManager', '', '', '', 'open', ',tester3,admin', 35, '0'),
-(6, 0, '', 'program', 'single', 'sprint', '0', 'CNY', '', 0, '0', '', '', 0, ',6,', 1, '企业管理', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '', '', '', 'open', '', 30, '0');
+INSERT INTO `zt_project` (`id`, `project`, `model`, `type`, `lifetime`, `budget`, `budgetUnit`, `attribute`, `percent`, `milestone`, `output`, `auth`, `parent`, `path`, `grade`, `name`, `code`, `begin`, `end`, `realBegan`, `realEnd`, `days`, `status`, `subStatus`, `pri`, `desc`, `version`, `parentVersion`, `planDuration`, `realDuration`, `openedBy`, `openedDate`, `openedVersion`, `lastEditedBy`, `lastEditedDate`, `closedBy`, `closedDate`, `canceledBy`, `canceledDate`, `PO`, `PM`, `QD`, `RD`, `team`, `acl`, `whitelist`, `order`, `deleted`) VALUES
+(1, 7, '', 'sprint', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,1,', 1, '企业网站第一期', 'coWeb1', '2020-06-05', '2021-12-04', '0000-00-00', '0000-00-00', 391, 'doing', '', '1', '开发企业网站的基本雏形。
', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 5, '0'),
+(2, 7, '', 'sprint', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,2,', 1, '企业网站第二期', 'coWebsite2', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 260, 'wait', '', '1', '', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 10, '0'),
+(7, 0, 'scrum', 'project', 'sprint', '0', 'CNY', '', 0, '0', '', 'extend', 6, ',6,7,', 2, '企业管理系统', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', 'admin', '2021-04-28 11:22:04', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 'projectManager', '', '', '', 'open', ',tester3,admin', 35, '0'),
+(6, 0, '', 'program', 'sprint', '0', 'CNY', '', 0, '0', '', '', 0, ',6,', 1, '企业管理', '', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 0, 'doing', '', '1', '', 0, 0, 0, 0, 'admin', '2021-04-28 11:22:04', '15.0.rc3', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '', '', '', 'open', '', 30, '0');
INSERT INTO `zt_projectcase` (`project`, `product`, `case`, `count`, `version`, `order`) VALUES
(1, 1, 2, 1, 1, 4),
(7, 1, 1, 1, 1, 5),
diff --git a/extension/qucheng b/extension/qucheng
deleted file mode 160000
index 14b5630326..0000000000
--- a/extension/qucheng
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 14b5630326a3b24fd385654629a77a19fcd62f59
diff --git a/lib/base/filter/filter.class.php b/lib/base/filter/filter.class.php
index 8db2523369..020f440076 100644
--- a/lib/base/filter/filter.class.php
+++ b/lib/base/filter/filter.class.php
@@ -1370,4 +1370,23 @@ class baseFixer
foreach($fields as $key => $fieldName) if(!isset($this->data->$fieldName)) unset($fields[$key]);
return $fields;
}
+
+ /**
+ * 过滤Emoji表情。
+ * Filter Emoji.
+ *
+ * @param string $fieldName
+ * @access public
+ * @return object
+ */
+ public function filterEmoji($fieldName){
+ $fields = $this->processFields($fieldName);
+ foreach($fields as $fieldName)
+ {
+ $this->data->$fieldName = preg_replace_callback('/./u', function (array $match){
+ return strlen($match[0]) >= 4 ? '' : $match[0];
+ }, $this->data->$fieldName);
+ }
+ return $this;
+ }
}
diff --git a/module/api/model.php b/module/api/model.php
index 4454e040a2..ff64cbdfbd 100644
--- a/module/api/model.php
+++ b/module/api/model.php
@@ -850,6 +850,6 @@ class apiModel extends model
private function getDemoData($table, $version)
{
$file = $this->app->getAppRoot() . 'db' . DS . 'api' . DS . $version . DS . $table;
- return unserialize(file_get_contents($file));
+ return unserialize(preg_replace_callback('#s:(\d+):"(.*?)";#s', function($match){return 's:'.strlen($match[2]).':"'.$match[2].'";';}, file_get_contents($file)));
}
}
diff --git a/module/block/control.php b/module/block/control.php
index 2ed074a095..1b08f2b03c 100644
--- a/module/block/control.php
+++ b/module/block/control.php
@@ -1708,8 +1708,8 @@ class block extends control
if(common::hasPriv('todo', 'view')) $hasViewPriv['todo'] = true;
if(common::hasPriv('task', 'view')) $hasViewPriv['task'] = true;
if(common::hasPriv('bug', 'view') and $this->config->vision != 'lite') $hasViewPriv['bug'] = true;
- if(common::hasPriv('story', 'view') and $this->config->vision != 'lite') $hasViewPriv['story'] = true;
if($this->config->URAndSR and common::hasPriv('story', 'view') and $this->config->vision != 'lite') $hasViewPriv['requirement'] = true;
+ if(common::hasPriv('story', 'view') and $this->config->vision != 'lite') $hasViewPriv['story'] = true;
if(common::hasPriv('risk', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['risk'] = true;
if(common::hasPriv('issue', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['issue'] = true;
if(common::hasPriv('meeting', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite') $hasViewPriv['meeting'] = true;
diff --git a/module/block/view/todoblock.html.php b/module/block/view/todoblock.html.php
index 2c55aa2355..070cea49f2 100644
--- a/module/block/view/todoblock.html.php
+++ b/module/block/view/todoblock.html.php
@@ -83,7 +83,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
@@ -182,6 +182,9 @@ if(!$selfCall) die(include('./todolist.html.php'));
setTimeout('clearError()', 2000)
return false;
}
+
+ $('.commitButton').addClass('disabled');
+
$.ajax(
{
type: "POST",
diff --git a/module/branch/control.php b/module/branch/control.php
index d68b02f74f..97304eba34 100644
--- a/module/branch/control.php
+++ b/module/branch/control.php
@@ -25,7 +25,10 @@ class branch extends control
*/
public function manage($productID, $browseType = 'active', $orderBy = 'order', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
- $this->loadModel('product')->setMenu($productID);
+ $product = $this->loadModel('product')->getById($productID);
+ if($product->type == 'normal') $this->locate($this->createLink('product', 'view', "productID=$productID"));
+
+ $this->product->setMenu($productID);
$this->session->set('branchManage', $this->app->getURI(true), 'product');
$this->branch->changeBranchLanguage($productID);
diff --git a/module/branch/model.php b/module/branch/model.php
index 5ea7207c1f..ff54cb859b 100644
--- a/module/branch/model.php
+++ b/module/branch/model.php
@@ -504,7 +504,6 @@ class branchModel extends model
}
else
{
- $branchGroups[$branch->product][0] = $this->lang->branch->main;
$branchGroups[$branch->product][$branch->id] = htmlspecialchars_decode($branch->name);
}
}
diff --git a/module/bug/control.php b/module/bug/control.php
index 4decd84b84..92f7ba569d 100644
--- a/module/bug/control.php
+++ b/module/bug/control.php
@@ -570,8 +570,8 @@ class bug extends control
if($projectID)
{
- $project = $this->loadModel('project')->getByID($projectID);
- if(empty($bugID)) $projects = array($projectID => $project->name);
+ $project = $this->loadModel('project')->getByID($projectID);
+ if(empty($bugID) or $this->app->tab != 'qa') $projects = array($projectID => $project->name);
}
}
elseif($projectID)
@@ -580,8 +580,8 @@ class bug extends control
$productList = $this->config->CRProduct ? $this->product->getOrderedProducts('all', 40, $projectID) : $this->product->getOrderedProducts('normal', 40, $projectID);
foreach($productList as $product) $products[$product->id] = $product->name;
- $project = $this->loadModel('project')->getByID($projectID);
- if(empty($bugID)) $projects += array($projectID => $project->name);
+ $project = $this->loadModel('project')->getByID($projectID);
+ if(empty($bugID) or $this->app->tab != 'qa') $projects += array($projectID => $project->name);
/* Set project menu. */
if($this->app->tab == 'project') $this->project->setMenu($projectID);
@@ -591,8 +591,8 @@ class bug extends control
$projects += $this->product->getProjectPairsByProduct($productID, $branch);
}
- /* When copying bug, get all project linked to the product. */
- if(!empty($bugID)) $projects += $this->product->getProjectPairsByProduct($productID, $branch);
+ /* Link all projects to product when copying bug under qa.*/
+ if(!empty($bugID) and $this->app->tab == 'qa') $projects += $this->product->getProjectPairsByProduct($productID, $branch);
/* Get block id of assinge to me. */
$blockID = 0;
diff --git a/module/common/model.php b/module/common/model.php
index bd0356c27a..326a822199 100644
--- a/module/common/model.php
+++ b/module/common/model.php
@@ -2332,6 +2332,7 @@ EOD;
if(empty($acls['views'])) return true;
$menu = isset($lang->navGroup->$module) ? $lang->navGroup->$module : $module;
+ if($module == 'my' && $method == 'team') $menu = 'system'; // Fix bug #18642.
$menu = strtolower($menu);
if($menu != 'qa' and !isset($lang->$menu->menu)) return true;
if(($menu == 'my' && $method != 'team')or $menu == 'index' or $module == 'tree') return true;
diff --git a/module/doc/js/view.js b/module/doc/js/view.js
index c4e9520f76..99bb339fee 100644
--- a/module/doc/js/view.js
+++ b/module/doc/js/view.js
@@ -1,12 +1,5 @@
$(function()
{
- if($('#urlIframe').size() > 0)
- {
- var defaultHeight = $.cookie('windowHeight') - $('#header').height() - $('#footer').height() - $('#mainMenu').height() - 50;
- $('#urlIframe').height(defaultHeight);
- setTimeout($.resetToolbarPosition, 50);
- }
-
var isFullscreen = $.cookie('docFullscreen') == 'true';
$('body').toggleClass('doc-fullscreen', isFullscreen);
$('.side-col').toggleClass('hidden', isFullscreen);
@@ -33,6 +26,13 @@ $(function()
$(this).find('a[onclick^=deleteFile]').remove();
});
}
+
+ if($('#urlIframe').size() > 0)
+ {
+ var defaultHeight = $('#mainContent .main-col').height() - 50;
+ $('#urlIframe').height(defaultHeight);
+ setTimeout($.resetToolbarPosition, 50);
+ }
})
function deleteFile(fileID)
diff --git a/module/doc/model.php b/module/doc/model.php
index b7890c1816..49a7b36aeb 100644
--- a/module/doc/model.php
+++ b/module/doc/model.php
@@ -1826,9 +1826,8 @@ class docModel extends model
*/
public function getStatisticInfo()
{
- $libIdList = array();
- $libIdList = $this->getLibIdListByProject($this->session->project);
- $docIdList = $this->getPrivDocs($libIdList);
+ $allLibs = array_keys($this->getLibs('all'));
+ $docIdList = $this->getPrivDocs($allLibs);
$today = date('Y-m-d');
$lately = date('Y-m-d', strtotime('-3 day'));
@@ -2672,6 +2671,7 @@ EOT;
$autoloadPage = true;
if(!empty($doc) and $doc->type == 'url')
{
+ if(!preg_match('/^https?:\/\//', $doc->content)) $doc->content = 'http://' . $doc->content;
$parsedUrl = parse_url($doc->content);
$urlPort = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
$urlDomain = $parsedUrl['host'] . $urlPort;
diff --git a/module/doc/view/index.html.php b/module/doc/view/index.html.php
index 76807bdacd..f3861e2316 100644
--- a/module/doc/view/index.html.php
+++ b/module/doc/view/index.html.php
@@ -135,7 +135,7 @@
createLink('doc', 'browse', "browseType=openedbyme"), '', '', "title='{$lang->more}'");?>
-
+
diff --git a/module/execution/control.php b/module/execution/control.php
index 0a963e0551..904db8455a 100644
--- a/module/execution/control.php
+++ b/module/execution/control.php
@@ -1631,7 +1631,7 @@ class execution extends control
$this->view->productPlans = $productPlans;
$this->view->branchGroups = $this->execution->getBranchByProduct(array_keys($linkedProducts), $this->config->systemMode == 'new' ? $execution->project : 0, 'noclosed', $linkedBranchList);
$this->view->teamMembers = $this->execution->getTeamMembers($executionID);
- if($this->config->systemMode == 'new') $this->view->allProjects = $this->project->getPairsByModel($project->model, 0, 'noclosed');
+ if($this->config->systemMode == 'new') $this->view->allProjects = $this->project->getPairsByModel($project->model, 0, 'noclosed', $project->id);
$this->display();
}
@@ -1677,8 +1677,9 @@ class execution extends control
if($this->app->tab == 'project')
{
- $this->project->setMenu($this->session->project);
- $this->view->project = $this->project->getById($this->session->project);
+ $projectID = $this->session->project;
+ $this->project->setMenu($projectID);
+ $this->view->project = $this->project->getById($projectID);
}
if(!$this->post->executionIDList) return print(js::locate($this->session->executionList, 'parent'));
@@ -1716,7 +1717,7 @@ class execution extends control
$this->view->position[] = $this->lang->execution->batchEdit;
$this->view->executionIDList = $executionIDList;
$this->view->executions = $executions;
- $this->view->allProjects = $this->project->getPairsByModel('all', 0, 'noclosed');
+ $this->view->allProjects = $this->project->getPairsByModel('all', 0, 'noclosed', isset($projectID) ? $projectID : 0);
$this->view->pmUsers = $pmUsers;
$this->view->poUsers = $poUsers;
$this->view->qdUsers = $qdUsers;
diff --git a/module/execution/css/kanban.css b/module/execution/css/kanban.css
index 00a13ba1a2..86fdfcfac8 100644
--- a/module/execution/css/kanban.css
+++ b/module/execution/css/kanban.css
@@ -43,6 +43,7 @@
.region .kanban-header-col > .actions {position: relative; right: 5px;}
.region .kanban-header-parent-col > .actions {position: absolute; right: 0px;}
.region .kanban-header-sub-cols .actions {position: absolute; right: 0px;}
+.region .kanban.kanban-dragging {overflow: hidden;}
.region .kanban-lane {position: relative; border-bottom: none!important; min-height: 200px !important}
diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js
index 8cb29abfe6..ff3a64f56c 100644
--- a/module/execution/js/kanban.js
+++ b/module/execution/js/kanban.js
@@ -295,7 +295,7 @@ function createColumnCreateMenu(options)
{
if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&todoID=0&extra=regionID=" + regionID + ",laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&iframe=0&extra=regionID=" + regionID + ",laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
- if(priv.canImportBug && vision == 'rnd') items.push({label: executionLang.importBug, url: $.createLink('execution', 'importBug', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&todoID=0&extra=laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
+ if(priv.canImportBug && vision == 'rnd') items.push({label: executionLang.importBug, url: $.createLink('execution', 'importBug', 'executionID=' + executionID + "&storyID=0&moduleID=0&taskID=0&todoID=0&extra=laneID=" + laneID + ",columnID=" + col.id, '', true), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '90%'}});
}
return items;
}
diff --git a/module/execution/js/taskkanban.js b/module/execution/js/taskkanban.js
index 8d7ee93d06..8df8beb996 100644
--- a/module/execution/js/taskkanban.js
+++ b/module/execution/js/taskkanban.js
@@ -836,7 +836,7 @@ function createColumnCreateMenu(options)
{
if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '80%'}});
if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '80%'}});
- if(priv.canImportBug) items.push({label: executionLang.importBug, url: $.createLink('execution', 'importBug', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '80%'}});
+ if(priv.canImportBug) items.push({label: executionLang.importBug, url: $.createLink('execution', 'importBug', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '90%'}});
}
return items;
}
diff --git a/module/execution/js/view.js b/module/execution/js/view.js
new file mode 100644
index 0000000000..92fe169bf3
--- /dev/null
+++ b/module/execution/js/view.js
@@ -0,0 +1,35 @@
+(function()
+{
+ /* Expand or collapse text */
+ function limitText()
+ {
+ var fullText;
+ var limitText;
+ var $text = $(this);
+ var options = $.extend({limitSize: 40, suffix: '…'}, $text.data());
+ var text = $text.text();
+ if(text.length > options.limitSize)
+ {
+ fullText = $text.html();
+ limitText = text.substring(0, options.limitSize) + options.suffix;
+ $text.text(limitText).addClass('limit-text-on');
+
+ var $toggleBtn = options.toggleBtn ? $(options.toggleBtn) : $text.next('.text-limit-toggle');
+ $toggleBtn.text($toggleBtn.data('textExpand'));
+ $toggleBtn.on('click', function()
+ {
+ var isLimitOn = $text.toggleClass('limit-text-on').hasClass('limit-text-on');
+ if(isLimitOn) $text.text(limitText);
+ else $text.html(fullText);
+ $toggleBtn.text($toggleBtn.data(isLimitOn ? 'textExpand' : 'textCollapse'));
+ });
+ }
+ else
+ {
+ (options.toggleBtn ? $(options.toggleBtn) : $text.next('.text-limit-toggle')).hide();
+ }
+ $text.removeClass('hidden');
+ };
+ $.fn.textLimit = function(){return this.each(limitText);};
+ $(function(){$('.text-limit').textLimit();});
+})();
diff --git a/module/execution/view/view.html.php b/module/execution/view/view.html.php
index a2de707acb..33b3a87e02 100644
--- a/module/execution/view/view.html.php
+++ b/module/execution/view/view.html.php
@@ -176,7 +176,7 @@
id;?> code;?> name;?>
-
+
deleted):?>
execution->deleted;?>
diff --git a/module/extension/model.php b/module/extension/model.php
index d1389dddec..29de175bba 100644
--- a/module/extension/model.php
+++ b/module/extension/model.php
@@ -617,7 +617,7 @@ class extensionModel extends model
foreach($dirs as $dir)
{
if(!is_dir($appRoot . $dir)) continue;
- if(!rmdir($appRoot . $dir)) $removeCommands[] = "rmdir $appRoot$dir"; // fix bug #2965
+ if(!rmdir($appRoot . $dir)) $removeCommands[] = PHP_OS == 'Linux' ? "rm -fr $appRoot$dir" : "rmdir $appRoot$dir /s /q";
}
}
diff --git a/module/group/view/browse.html.php b/module/group/view/browse.html.php
index 39ea964236..6fc067639f 100644
--- a/module/group/view/browse.html.php
+++ b/module/group/view/browse.html.php
@@ -45,8 +45,8 @@
role == 'projectAdmin';?>
group->managepriv = $lang->group->managePrivByGroup;?>
- id", $group, 'list', 'eye', '', "$disabled");?>
- id", $group, 'list', 'lock');?>
+ id", $group, 'list', 'eye', '', $disabled);?>
+ id", $group, 'list', 'lock', '', $disabled);?>
group->managemember = $lang->group->manageMember;?>
id", $group, 'list', 'persons');?>
diff --git a/module/kanban/css/view.css b/module/kanban/css/view.css
index 8a8496bca6..52ff8d0e5b 100644
--- a/module/kanban/css/view.css
+++ b/module/kanban/css/view.css
@@ -23,6 +23,7 @@
.region .kanban-header-sub-cols {margin-left:0;}
.region .kanban-header-sub-cols .kanban-header-col > .title {max-width: 100% !important;min-width:240px;}
.region .sort .region-header {cursor: move;}
+.region .kanban.kanban-dragging {overflow: hidden;}
.region .kanban {padding: 0px 5px 10px 10px; min-height: unset; overflow:auto; width: 100%}
.region .kanban .form-actions {margin: 0;}
diff --git a/module/project/js/view.js b/module/project/js/view.js
new file mode 100644
index 0000000000..92fe169bf3
--- /dev/null
+++ b/module/project/js/view.js
@@ -0,0 +1,35 @@
+(function()
+{
+ /* Expand or collapse text */
+ function limitText()
+ {
+ var fullText;
+ var limitText;
+ var $text = $(this);
+ var options = $.extend({limitSize: 40, suffix: '…'}, $text.data());
+ var text = $text.text();
+ if(text.length > options.limitSize)
+ {
+ fullText = $text.html();
+ limitText = text.substring(0, options.limitSize) + options.suffix;
+ $text.text(limitText).addClass('limit-text-on');
+
+ var $toggleBtn = options.toggleBtn ? $(options.toggleBtn) : $text.next('.text-limit-toggle');
+ $toggleBtn.text($toggleBtn.data('textExpand'));
+ $toggleBtn.on('click', function()
+ {
+ var isLimitOn = $text.toggleClass('limit-text-on').hasClass('limit-text-on');
+ if(isLimitOn) $text.text(limitText);
+ else $text.html(fullText);
+ $toggleBtn.text($toggleBtn.data(isLimitOn ? 'textExpand' : 'textCollapse'));
+ });
+ }
+ else
+ {
+ (options.toggleBtn ? $(options.toggleBtn) : $text.next('.text-limit-toggle')).hide();
+ }
+ $text.removeClass('hidden');
+ };
+ $.fn.textLimit = function(){return this.each(limitText);};
+ $(function(){$('.text-limit').textLimit();});
+})();
diff --git a/module/project/model.php b/module/project/model.php
index 8b5db8db7e..0ae9c93ae7 100644
--- a/module/project/model.php
+++ b/module/project/model.php
@@ -678,12 +678,14 @@ class projectModel extends model
/**
* Get project pairs by model and project.
*
- * @param string $model all|scrum|waterfall|kanban
- * @param int $programID
+ * @param string $model all|scrum|waterfall|kanban
+ * @param int $programID
+ * @param string $param noclosed
+ * @param string|int|array $append
* @access public
* @return array
*/
- public function getPairsByModel($model = 'all', $programID = 0, $param = '')
+ public function getPairsByModel($model = 'all', $programID = 0, $param = '', $append = '')
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectPairs();
@@ -696,6 +698,7 @@ class projectModel extends model
->beginIF($model != 'all')->andWhere('model')->eq($model)->fi()
->beginIF(strpos($param, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi()
+ ->beginIF(!empty($append))->orWhere('id')->in($append)->fi()
->orderBy('id_desc')
->fetchAll();
@@ -906,8 +909,8 @@ class projectModel extends model
$this->dao->insert(TABLE_PROJECT)->data($project)
->autoCheck()
->batchcheck($requiredFields, 'notempty')
- ->checkIF(!empty($project->name), 'name', 'unique', "`type`='project' and `parent` = $project->parent")
- ->checkIF(!empty($project->code), 'code', 'unique', "`type`='project'")
+ ->checkIF(!empty($project->name), 'name', 'unique', "`type`='project' and `parent` = $project->parent and `model` = '{$project->model}'")
+ ->checkIF(!empty($project->code), 'code', 'unique', "`type`='project' and `model` = '{$project->model}'")
->checkIF($project->end != '', 'end', 'gt', $project->begin)
->exec();
@@ -1139,8 +1142,8 @@ class projectModel extends model
->checkIF($project->begin != '', 'begin', 'date')
->checkIF($project->end != '', 'end', 'date')
->checkIF($project->end != '', 'end', 'gt', $project->begin)
- ->checkIF(!empty($project->name), 'name', 'unique', "id != $projectID and `type` = 'project' and `parent` = $project->parent")
- ->checkIF(!empty($project->code), 'code', 'unique', "id != $projectID and `type` = 'project'")
+ ->checkIF(!empty($project->name), 'name', 'unique', "id != $projectID and `type` = 'project' and `parent` = $project->parent and `model` = '{$project->model}'")
+ ->checkIF(!empty($project->code), 'code', 'unique', "id != $projectID and `type` = 'project' and `model` = '{$project->model}'")
->where('id')->eq($projectID)
->exec();
@@ -1280,8 +1283,8 @@ class projectModel extends model
->checkIF($project->begin != '', 'begin', 'date')
->checkIF($project->end != '', 'end', 'date')
->checkIF($project->end != '', 'end', 'gt', $project->begin)
- ->checkIF(!empty($project->name), 'name', 'unique', "id != $projectID and `type`='project' and `parent` = $parentID")
- ->checkIF(!empty($project->code), 'code', 'unique', "id != $projectID and `type`='project'")
+ ->checkIF(!empty($project->name), 'name', 'unique', "id != $projectID and `type`='project' and `parent` = $parentID and `model` = '{$project->model}'")
+ ->checkIF(!empty($project->code), 'code', 'unique', "id != $projectID and `type`='project' and `model` = '{$project->model}'")
->where('id')->eq($projectID)
->exec();
diff --git a/module/project/view/view.html.php b/module/project/view/view.html.php
index 085887fa70..562956096c 100644
--- a/module/project/view/view.html.php
+++ b/module/project/view/view.html.php
@@ -125,7 +125,7 @@
id;?> code;?> name;?>
-
+
deleted):?>
project->deleted;?>
diff --git a/module/repo/model.php b/module/repo/model.php
index bb0b28c688..2a54926e2e 100644
--- a/module/repo/model.php
+++ b/module/repo/model.php
@@ -200,6 +200,12 @@ class repoModel extends model
if(!$this->checkClient()) return false;
if(!$this->checkConnection()) return false;
+ if($this->post->SCM == 'Gitlab')
+ {
+ if($this->post->gitlabHost == '') dao::$errors['gitlabHost'] = sprintf($this->lang->error->notempty, $this->lang->repo->gitlabHost);
+ if($this->post->gitlabProject == '') dao::$errors['gitlabProject'] = sprintf($this->lang->error->notempty, $this->lang->repo->gitlabProject);
+ }
+
$data = fixer::input('post')
->setIf($this->post->SCM == 'Gitlab', 'password', $this->post->gitlabToken)
->setIf($this->post->SCM == 'Gitlab', 'path', $this->post->gitlabProject)
@@ -262,6 +268,12 @@ class repoModel extends model
{
$repo = $this->getRepoByID($id);
+ if($this->post->SCM == 'Gitlab')
+ {
+ if($this->post->gitlabHost == '') dao::$errors['gitlabHost'] = sprintf($this->lang->error->notempty, $this->lang->repo->gitlabHost);
+ if($this->post->gitlabProject == '') dao::$errors['gitlabProject'] = sprintf($this->lang->error->notempty, $this->lang->repo->gitlabProject);
+ }
+
$data = fixer::input('post')
->setIf($this->post->SCM == 'Gitlab', 'password', $this->post->gitlabToken)
->setIf($this->post->SCM == 'Gitlab', 'path', $this->post->gitlabProject)
@@ -1149,7 +1161,12 @@ class repoModel extends model
{
if($this->post->SCM == 'Gitlab') return true;
if(!$this->config->features->checkClient) return true;
- if(!$this->post->client) return true;
+
+ if(!$this->post->client)
+ {
+ dao::$errors['client'] = sprintf($this->lang->error->notempty, $this->lang->repo->client);
+ return false;
+ }
if(strpos($this->post->client, ' '))
{
diff --git a/module/search/model.php b/module/search/model.php
index 09aff5165d..770c90cc3f 100644
--- a/module/search/model.php
+++ b/module/search/model.php
@@ -399,7 +399,6 @@ class searchModel extends model
public function deleteQuery($queryID)
{
$this->dao->delete()->from(TABLE_USERQUERY)->where('id')->eq($queryID)->andWhere('account')->eq($this->app->user->account)->exec();
- echo 'success';
}
/**
diff --git a/module/search/view/buildform.html.php b/module/search/view/buildform.html.php
index 4b1efa682f..7af76e8e24 100644
--- a/module/search/view/buildform.html.php
+++ b/module/search/view/buildform.html.php
@@ -546,6 +546,7 @@ $(function()
if($('#formType').val() == 'more') expandForm(true);
$searchForm.on('click', '.user-query .icon-close', function(e)
{
+ e.preventDefault(); // Fix bug #21572.
var $query = $(this).closest('.user-query');
var queryId = $query.data('queryId');
var deleteQueryLink = $.createLink('search', 'deleteQuery', 'queryID=' + queryId);
diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php
index 9d43318036..f0c8895767 100644
--- a/module/story/view/view.html.php
+++ b/module/story/view/view.html.php
@@ -305,7 +305,7 @@
?>
|
- type != 'requirement'):?>
+ type != 'requirement' and $story->parent != -1):?>
| story->plan;?> |
diff --git a/module/testcase/control.php b/module/testcase/control.php
index 3809d8dbec..85bda938e8 100644
--- a/module/testcase/control.php
+++ b/module/testcase/control.php
@@ -216,7 +216,7 @@ class testcase extends control
$this->view->browseType = $browseType;
$this->view->param = $param;
$this->view->cases = $cases;
- $this->view->branch = !empty($product) and $product->type != 'normal' ? $branch : 0;
+ $this->view->branch = (!empty($product) and $product->type != 'normal') ? $branch : 0;
$this->view->branchOption = $branchOption;
$this->view->branchTagOption = $branchTagOption;
$this->view->suiteList = $this->loadModel('testsuite')->getSuites($productID);
diff --git a/module/testcase/model.php b/module/testcase/model.php
index 1158b7b9b7..5a40c8347f 100644
--- a/module/testcase/model.php
+++ b/module/testcase/model.php
@@ -71,7 +71,9 @@ class testcaseModel extends model
$this->loadModel('file')->saveUpload('testcase', $caseID);
$parentStepID = 0;
$this->loadModel('score')->create('testcase', 'create', $caseID);
- foreach($this->post->steps as $stepID => $stepDesc)
+
+ $data = fixer::input('post')->filterEmoji('steps,expects')->get();
+ foreach($data->steps as $stepID => $stepDesc)
{
if(empty($stepDesc)) continue;
$stepType = $this->post->stepType;
@@ -81,7 +83,7 @@ class testcaseModel extends model
$step->case = $caseID;
$step->version = 1;
$step->desc = htmlSpecialString($stepDesc);
- $step->expect = $step->type == 'group' ? '' : htmlSpecialString($this->post->expects[$stepID]);
+ $step->expect = $step->type == 'group' ? '' : htmlSpecialString($data->expects[$stepID]);
$this->dao->insert(TABLE_CASESTEP)->data($step)->autoCheck()->exec();
if($step->type == 'group') $parentStepID = $this->dao->lastInsertID();
if($step->type == 'step') $parentStepID = 0;
@@ -741,7 +743,9 @@ class testcaseModel extends model
/* Ignore steps when post has no steps. */
if($this->post->steps)
{
- foreach($this->post->steps as $stepID => $stepDesc)
+ $data = fixer::input('post')->filterEmoji('steps,expects')->get();
+
+ foreach($data->steps as $stepID => $stepDesc)
{
if(empty($stepDesc)) continue;
$stepType = $this->post->stepType;
@@ -751,7 +755,7 @@ class testcaseModel extends model
$step->case = $caseID;
$step->version = $version;
$step->desc = htmlSpecialString($stepDesc);
- $step->expect = $step->type == 'group' ? '' : htmlSpecialString($this->post->expects[$stepID]);
+ $step->expect = $step->type == 'group' ? '' : htmlSpecialString($data->expects[$stepID]);
$this->dao->insert(TABLE_CASESTEP)->data($step)->autoCheck()->exec();
if($step->type == 'group') $parentStepID = $this->dao->lastInsertID();
if($step->type == 'step') $parentStepID = 0;
diff --git a/module/todo/view/batchcreate.html.php b/module/todo/view/batchcreate.html.php
index 876c324fb9..6a16e94fb3 100755
--- a/module/todo/view/batchcreate.html.php
+++ b/module/todo/view/batchcreate.html.php
@@ -51,7 +51,7 @@
| todo->name;?> |
'>todo->desc;?> |
'>todo->beginAndEnd;?> |
- |
+ ' style='overflow:visible' id="select-all"> |
diff --git a/module/user/lang/de.php b/module/user/lang/de.php
index e1fac43bbf..5e3bf4ef5f 100644
--- a/module/user/lang/de.php
+++ b/module/user/lang/de.php
@@ -257,8 +257,8 @@ $lang->user->mkdirLinux = <<
|
不能创建临时目录,请确认目录%s是否存在并有操作权限。
- 命令为:chmod o=rwx -R %s。
+ 命令为:chmod 777 -R %s。
Can't create tmp directory, make sure the directory %s exists and has permission to operate.
- Commond: chmod o=rwx -R %s.
+ Commond: chmod 777 -R %s.
|