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

This commit is contained in:
liyang
2022-04-07 15:30:29 +08:00
493 changed files with 12018 additions and 2409 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "extension/qucheng"]
path = extension/qucheng
url = https://gitlab.zcorp.cc/easycorp/qucheng.git
+1 -1
View File
@@ -1 +1 @@
16.5.beta1
16.5
+1 -1
View File
@@ -79,7 +79,7 @@ class bugsEntry extends entry
if(!$productID and isset($this->requestBody->product)) $productID = $this->requestBody->product;
if(!$productID) return $this->sendError(400, 'Need product id.');
$fields = 'title,project,execution,openedBuild,assignedTo,pri,module,severity,type,story,task,mailto,keywords,steps';
$fields = 'title,project,execution,openedBuild,assignedTo,pri,module,severity,type,story,task,mailto,keywords,steps,uid';
$this->batchSetPost($fields);
$this->setPost('product', $productID);
+30
View File
@@ -0,0 +1,30 @@
<?php
/**
* The ciresults entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class ciresultsEntry extends entry
{
/**
* POST method.
*
* @access public
* @return void
*/
public function post()
{
$control = $this->loadController('ci', 'commitResult');
$control->commitResult();
$data = $this->getData();
if(isset($data->result) and $data->result == 'fail') return $this->sendError(400, $data->message);
$this->send(201, array());
}
}
+2 -2
View File
@@ -58,7 +58,7 @@ class productEntry extends Entry
$product->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($productID, 'bug', 0, 'all');
break;
case 'builds':
$product->builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,noterminate,nodone,withbranch');
$product->builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'noempty,noterminate,nodone,withbranch', $this->param('object', 0), $this->param('objectType', 'execution'));
break;
case 'actions':
$product->addComment = common::hasPriv('action', 'comment') ? true : false;
@@ -68,7 +68,7 @@ class productEntry extends Entry
$product->actions = $this->loadModel('action')->processActionForAPI($actions, $users, $this->lang->product);
break;
case 'lastexecution':
$execution = $this->dao->select('t2.id,t2.name')->from(TABLE_PROJECTPRODUCT)->alias('t1')
$execution = $this->dao->select('t2.id,t2.name,t2.type')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t2.deleted')->eq(0)
->andWhere('t1.product')->eq($productID)
+1 -1
View File
@@ -66,7 +66,7 @@ class storiesEntry extends entry
$control = $this->loadController('story', 'create');
$this->requireFields('title,spec,pri,category');
$control->create($productID);
$control->create($productID, $this->param('branch', 0), $this->param('moduleID', 0), $this->param('storyID', 0), $this->param('objectID', 0));
$data = $this->getData();
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
+1 -3
View File
@@ -95,14 +95,12 @@ class storyEntry extends Entry
$oldStory = $this->loadModel('story')->getByID($storyID);
/* Set $_POST variables. */
$fields = 'title,product,reviewer,type,plan,module,source,sourceNote,category,pri,estimate,mailto,keywords,uid,stage,notifyEmail';
$fields = 'title,product,parent,reviewer,type,plan,module,source,sourceNote,category,pri,estimate,mailto,keywords,uid,stage,notifyEmail';
$this->batchSetPost($fields, $oldStory);
$this->setPost('parent', 0);
$control = $this->loadController('story', 'edit');
$control->edit($storyID);
$data = $this->getData();
if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message);
+1 -1
View File
@@ -22,7 +22,7 @@ class storyAssignToEntry extends Entry
{
$story = $this->loadModel('story')->getByID($storyID);
$fields = 'assignedTo';
$fields = 'assignedTo,comment';
$this->batchSetPost($fields);
$control = $this->loadController('story', 'assignTo');
+2 -2
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '16.5.beta1'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '16.5'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->liteVersion = '1.0'; // 迅捷版版本。 The version of Lite.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
@@ -146,7 +146,7 @@ $config->file->allowed = 'txt,doc,docx,dot,wps,wri,pdf,ppt,pptx,xls,xlsx,ett
$config->file->storageType = 'fs'; // fs or s3
/* Upload settings. */
$config->allowedTags = '<p><span><h1><h2><h3><h4><h5><em><u><strong><br><ol><ul><li><img><a><b><font><hr><pre><div><table><td><th><tr><tbody><embed><style>';
$config->allowedTags = '<p><span><h1><h2><h3><h4><h5><em><u><strong><br><ol><ul><li><img><a><b><font><hr><pre><div><table><td><th><tr><tbody><embed><style><s>';
$config->accountRule = '|^[a-zA-Z0-9_]{1}[a-zA-Z0-9_\.]{1,}[a-zA-Z0-9_]{1}$|';
$config->checkVersion = true; // Auto check for new version or not.
+1
View File
@@ -250,6 +250,7 @@ $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->export->cookie['involved'] = 'code';
$filter->project->browse->cookie['projectType'] = 'code';
$filter->project->story->cookie['storyModuleParam'] = 'int';
$filter->project->story->cookie['storyPreProjectID'] = 'int';
+2
View File
@@ -158,4 +158,6 @@ $routes['/z/files/:id/content'] = 'zfileContent';
$routes['/gitlab/webhook'] = 'gitlabWebhook';
$routes['/ciresults'] = 'ciresults';
$config->routes = $routes;
+1
View File
@@ -218,6 +218,7 @@ $config->openMethods[] = 'kanban.activatecard';
$config->openMethods[] = 'kanban.finishcard';
$config->openMethods[] = 'kanban.deleteobjectcard';
$config->openMethods[] = 'admin.ignore';
$config->openMethods[] = 'personnel.unbindwhitelist';
/* Define the tables. */
define('TABLE_COMPANY', '`' . $config->db->prefix . 'company`');
+8 -8
View File
@@ -377,16 +377,16 @@ INSERT INTO `zt_module` (`id`, `root`, `branch`, `name`, `parent`, `path`, `grad
(13, 1, 0, '合作洽谈', 0, ',13,', 1, 60, 'bug', '', '', '', '0'),
(14, 1, 0, '关于我们', 0, ',14,', 1, 70, 'bug', '', '', '', '0'),
(15, 6, 0, '企业管理', 0, ',15,', 1, 0, 'line', '', '', '', '0');
INSERT INTO `zt_product` (`id`, `program`, `name`, `code`, `bind`, `line`, `type`, `status`, `subStatus`, `desc`, `PO`, `QD`, `RD`, `acl`, `whitelist`, `createdBy`, `createdDate`, `createdVersion`, `order`, `deleted`, `storyConcept`) VALUES
(1, 6, '公司企业网站建设', 'companyWebsite', '0', 0, 'normal', 'normal', '', '建立公司企业网站,可以更好对外展示。<br />', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 09:57:07', '', 5, '0', 0),
(2, 6, '企业内部工时管理系统', 'workhourManage', '0', 0, 'normal', 'normal', '', '', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 11:15:20', '5.2.1', 10, '0', 0);
INSERT INTO `zt_product` (`id`, `program`, `name`, `code`, `bind`, `line`, `type`, `status`, `subStatus`, `desc`, `PO`, `QD`, `RD`, `acl`, `whitelist`, `createdBy`, `createdDate`, `createdVersion`, `order`, `deleted`) VALUES
(1, 6, '公司企业网站建设', 'companyWebsite', '0', 0, 'normal', 'normal', '', '建立公司企业网站,可以更好对外展示。<br />', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 09:57:07', '', 5, '0'),
(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版本。<br />', '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`, `storyConcept`) 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', '开发企业网站的基本雏形。<br />', 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', 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', 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', 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', 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', '开发企业网站的基本雏形。<br />', 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_projectcase` (`project`, `product`, `case`, `count`, `version`, `order`) VALUES
(1, 1, 2, 1, 1, 4),
(7, 1, 1, 1, 1, 5),
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
ALTER TABLE `zt_vmtemplate` ADD COLUMN `name` varchar(255) NOT NULL AFTER `id`;
ALTER TABLE `zt_vmtemplate` CHANGE COLUMN `status` `osVersion` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' AFTER `osCategory`;
ALTER TABLE `zt_vmtemplate` ADD COLUMN `osLang` varchar(50) NOT NULL AFTER `osVersion`;
ALTER TABLE `zt_vmtemplate` ADD COLUMN `osArch` varchar(50) NOT NULL AFTER `osLang`;
ALTER TABLE `zt_vmtemplate` ADD COLUMN `cpuCoreNum` smallint(4) NOT NULL DEFAULT 0 AFTER `osLang`;
ALTER TABLE `zt_vmtemplate` ADD COLUMN `memorySize` int NOT NULL DEFAULT 0 AFTER `cpuCoreNum`;
ALTER TABLE `zt_vmtemplate` ADD COLUMN `diskSize` int NOT NULL DEFAULT 0 AFTER `memorySize`;
ALTER TABLE `zt_vm` ADD COLUMN `osCpu` tinyint(2) NOT NULL DEFAULT 0 AFTER `osLang`;
ALTER TABLE `zt_vm` ADD COLUMN `osMemory` smallint(6) NOT NULL DEFAULT 0 AFTER `osCpu`;
ALTER TABLE `zt_vm` ADD COLUMN `osDisk` smallint(6) NOT NULL DEFAULT 0 AFTER `osMemory`;
ALTER TABLE `zt_vm` DROP COLUMN `ip`, DROP COLUMN `agentPort`;
ALTER TABLE `zt_vm` CHANGE COLUMN `vnc` `vncPort` int(10) NOT NULL DEFAULT 0 AFTER `heatbeat`;
+45
View File
@@ -0,0 +1,45 @@
ALTER TABLE `zt_api` MODIFY COLUMN `desc` mediumtext NULL;
ALTER TABLE `zt_apispec` MODIFY COLUMN `desc` mediumtext NULL;
ALTER TABLE `zt_apistruct` MODIFY COLUMN `desc` mediumtext NOT NULL DEFAULT '';
ALTER TABLE `zt_bug` MODIFY COLUMN `steps` mediumtext NOT NULL;
ALTER TABLE `zt_build` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_design` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_designspec` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_doclib` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_entry` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_extension` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_holiday` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_kanbanspace` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_kanban` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_kanbancard` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_product` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_productplan` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_project` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_release` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_storyspec` MODIFY COLUMN `spec` mediumtext NOT NULL;
ALTER TABLE `zt_storyspec` MODIFY COLUMN `verify` mediumtext NOT NULL;
ALTER TABLE `zt_task` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_testsuite` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_testtask` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_todo` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_service` MODIFY COLUMN `desc` mediumtext;
ALTER TABLE `zt_deploy` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_traincourse` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_activity` MODIFY COLUMN `content` mediumtext NOT NULL;
ALTER TABLE `zt_nc` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_zoutput` MODIFY COLUMN `content` mediumtext NOT NULL;
ALTER TABLE `zt_process` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_budget` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_researchplan` MODIFY COLUMN `outline` mediumtext NOT NULL;
ALTER TABLE `zt_researchplan` MODIFY COLUMN `schedule` mediumtext NOT NULL;
ALTER TABLE `zt_researchreport` MODIFY COLUMN `content` mediumtext NOT NULL;
ALTER TABLE `zt_assetlib` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_meastemplate` MODIFY COLUMN `content` mediumtext NOT NULL;
ALTER TABLE `zt_issue` MODIFY COLUMN `desc` mediumtext NOT NULL;
ALTER TABLE `zt_risk` MODIFY COLUMN `prevention` mediumtext NOT NULL;
ALTER TABLE `zt_risk` MODIFY COLUMN `remedy` mediumtext NOT NULL;
ALTER TABLE `zt_risk` MODIFY COLUMN `resolution` mediumtext NOT NULL;
ALTER TABLE `zt_opportunity` MODIFY COLUMN `prevention` mediumtext NOT NULL;
ALTER TABLE `zt_opportunity` MODIFY COLUMN `resolution` mediumtext NOT NULL;
ALTER TABLE `zt_trainplan` MODIFY COLUMN `summary` mediumtext NOT NULL;
ALTER TABLE `zt_gapanalysis` MODIFY COLUMN `analysis` mediumtext NOT NULL;
+56 -51
View File
@@ -55,7 +55,7 @@ CREATE TABLE `zt_api` (
`responseType` varchar(100) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
`owner` varchar(30) NOT NULl DEFAULT 0,
`desc` text NULL,
`desc` mediumtext NULL,
`version` smallint UNSIGNED NOT NULL DEFAULT 0,
`params` text NULL,
`paramsExample` text NUll,
@@ -82,7 +82,7 @@ CREATE TABLE `zt_apispec` (
`responseType` varchar(100) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
`owner` varchar(255) NOT NULl DEFAULT 0,
`desc` text NULL,
`desc` mediumtext NULL,
`version` smallint UNSIGNED NOT NULL DEFAULT 0,
`params` text NULL,
`paramsExample` text NUll,
@@ -98,7 +98,7 @@ CREATE TABLE `zt_apistruct` (
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`name` varchar(30) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` text NOT NULL DEFAULT '',
`desc` mediumtext NOT NULL DEFAULT '',
`version` smallint unsigned NOT NULL DEFAULT 0,
`attribute` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
@@ -177,7 +177,7 @@ CREATE TABLE IF NOT EXISTS `zt_bug` (
`browser` varchar(30) NOT NULL default '',
`hardware` varchar(30) NOT NULL,
`found` varchar(30) NOT NULL default '',
`steps` text NOT NULL,
`steps` mediumtext NOT NULL,
`status` enum('active','resolved','closed') NOT NULL default 'active',
`subStatus` varchar(30) NOT NULL default '',
`color` char(7) NOT NULL,
@@ -241,7 +241,7 @@ CREATE TABLE IF NOT EXISTS `zt_build` (
`stories` text NOT NULL,
`bugs` text NOT NULL,
`builder` char(30) NOT NULL default '',
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
@@ -419,7 +419,7 @@ CREATE TABLE IF NOT EXISTS `zt_design` (
`assignedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`story` char(30) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`version` smallint(6) NOT NULL,
`type` char(30) NOT NULL,
PRIMARY KEY (`id`)
@@ -429,7 +429,7 @@ CREATE TABLE IF NOT EXISTS `zt_designspec` (
`design` mediumint(8) NOT NULL,
`version` smallint(6) NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`files` varchar(255) NOT NULL,
UNIQUE KEY `design` (`design`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -491,7 +491,7 @@ CREATE TABLE IF NOT EXISTS `zt_doclib` (
`users` text NOT NULL,
`main` enum('0','1') NOT NULL default '0',
`collector` text NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`order` tinyint(5) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
@@ -524,7 +524,7 @@ CREATE TABLE IF NOT EXISTS `zt_entry` (
`key` varchar(32) NOT NULL,
`freePasswd` enum('0','1') NOT NULL DEFAULT '0',
`ip` varchar(100) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`calledTime` int(10) unsigned NOT NULL DEFAULT '0',
@@ -551,7 +551,7 @@ CREATE TABLE IF NOT EXISTS `zt_extension` (
`code` varchar(30) NOT NULL,
`version` varchar(50) NOT NULL,
`author` varchar(100) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`license` text NOT NULL,
`type` varchar(20) NOT NULL default 'extension',
`site` varchar(150) NOT NULL,
@@ -607,7 +607,7 @@ CREATE TABLE IF NOT EXISTS `zt_holiday` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '',
`type` enum('holiday', 'working') NOT NULL DEFAULT 'holiday',
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`year` char(4) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
@@ -661,7 +661,7 @@ CREATE TABLE `zt_kanbanspace` (
`type` varchar(50) NOT NULL,
`owner` varchar(30) NOT NULL,
`team` text NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`acl` char(30) NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`status` enum('active','closed') NOT NULL default 'active',
@@ -682,7 +682,7 @@ CREATE TABLE `zt_kanban` (
`name` varchar(255) NOT NULL,
`owner` varchar(30) NOT NULL,
`team` text NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`acl` char(30) NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`archived` enum('0', '1') NOT NULL DEFAULT '1',
@@ -727,7 +727,7 @@ CREATE TABLE `zt_kanbancard` (
`status` varchar(30) NOT NULL DEFAULT 'doing',
`pri` mediumint(8) unsigned NOT NULL,
`assignedTo` text NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`estimate` float unsigned NOT NULL,
@@ -955,7 +955,7 @@ CREATE TABLE IF NOT EXISTS `zt_product` (
`type` varchar(30) NOT NULL default 'normal',
`status` varchar(30) NOT NULL default '',
`subStatus` varchar(30) NOT NULL default '',
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`PO` varchar(30) NOT NULL,
`QD` varchar(30) NOT NULL,
`RD` varchar(30) NOT NULL,
@@ -980,7 +980,7 @@ CREATE TABLE IF NOT EXISTS `zt_productplan` (
`parent` mediumint(9) NOT NULL DEFAULT '0',
`title` varchar(90) NOT NULL,
`status` enum('wait','doing','done','closed') NOT NULL default 'wait',
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`order` text NOT NULL,
@@ -1017,7 +1017,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
`status` varchar(10) NOT NULL,
`subStatus` varchar(30) NOT NULL DEFAULT '',
`pri` enum('1','2','3','4') NOT NULL DEFAULT '1',
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`version` smallint(6) NOT NULL,
`parentVersion` smallint(6) NOT NULL,
`planDuration` int(11) NOT NULL,
@@ -1121,7 +1121,7 @@ CREATE TABLE IF NOT EXISTS `zt_release` (
`stories` text NOT NULL,
`bugs` text NOT NULL,
`leftBugs` text NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`mailto` text,
`notify` varchar(255),
`status` varchar(20) NOT NULL default 'normal',
@@ -1335,8 +1335,8 @@ CREATE TABLE IF NOT EXISTS `zt_storyspec` (
`story` mediumint(9) NOT NULL,
`version` smallint(6) NOT NULL,
`title` varchar(255) NOT NULL,
`spec` text NOT NULL,
`verify` text NOT NULL,
`spec` mediumtext NOT NULL,
`verify` mediumtext NOT NULL,
UNIQUE KEY `story` (`story`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_storystage`;
@@ -1379,7 +1379,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
`subStatus` varchar(30) NOT NULL default '',
`color` char(7) NOT NULL,
`mailto` text,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`version` smallint(6) NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
@@ -1516,7 +1516,7 @@ CREATE TABLE IF NOT EXISTS `zt_testsuite` (
`project` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`type` varchar(20) NOT NULL,
`addedBy` char(30) NOT NULL,
`addedDate` datetime NOT NULL,
@@ -1541,7 +1541,7 @@ CREATE TABLE IF NOT EXISTS `zt_testtask` (
`end` date NOT NULL,
`realFinishedDate` datetime NOT NULL,
`mailto` text,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`report` text NOT NULL,
`status` enum('blocked','doing','wait','done') NOT NULL DEFAULT 'wait',
`testreport` mediumint(8) unsigned NOT NULL,
@@ -1564,7 +1564,7 @@ CREATE TABLE IF NOT EXISTS `zt_todo` (
`idvalue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
`name` char(150) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`status` enum('wait','doing','done','closed') NOT NULL DEFAULT 'wait',
`private` tinyint(1) NOT NULL,
`config` varchar(255) NOT NULL,
@@ -6002,8 +6002,6 @@ INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'unitList', 'CNY,USD');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'defaultCurrency', 'CNY');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'story', '', 'reviewRules', 'allpass');
INSERT INTO `zt_config` (`vision`,`owner`, `module`, `section`, `key`, `value`) VALUES ('lite','system', 'project', '', 'unitList', 'CNY,USD');
INSERT INTO `zt_config` (`vision`,`owner`, `module`, `section`, `key`, `value`) VALUES ('lite','system', 'project', '', 'defaultCurrency', 'CNY');
-- DROP TABLE IF EXISTS `zt_im_chat`;
CREATE TABLE IF NOT EXISTS `zt_im_chat` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
@@ -6928,7 +6926,7 @@ CREATE TABLE IF NOT EXISTS `zt_service` (
`deploy` varchar(255) NOT NULL,
`version` varchar(64) NOT NULL,
`color` char(7) NOT NULL,
`desc` text,
`desc` mediumtext,
`dept` varchar(128) NOT NULL,
`devel` varchar(30) NOT NULL,
`qa` varchar(30) NOT NULL,
@@ -7113,7 +7111,7 @@ CREATE TABLE IF NOT EXISTS `zt_deploy` (
`begin` datetime NOT NULL,
`end` datetime NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`status` varchar(20) NOT NULL,
`owner` char(30) NOT NULL,
`members` text NOT NULL,
@@ -7170,10 +7168,11 @@ CREATE TABLE IF NOT EXISTS `zt_vm` (
`osType` varchar(50) NOT NULL DEFAULT '',
`osArch` varchar(50) NOT NULL DEFAULT '',
`osLang` varchar(50) NOT NULL DEFAULT '',
`osCpu` tinyint(2) NOT NULL DEFAULT 0,
`osMemory` smallint(6) NOT NULL DEFAULT 0,
`osDisk` smallint(6) NOT NULL DEFAULT 0,
`status` varchar(50) NOT NULL DEFAULT '',
`destroyAt` datetime NULL,
`ip` varchar(200) NOT NULL DEFAULT '',
`agentPort` varchar(255) NOT NULL DEFAULT '',
`macAddress` varchar(255) NOT NULL DEFAULT '',
`workspace` varchar(255) NOT NULL DEFAULT '',
`templateID` int(10) unsigned NOT NULL DEFAULT 0,
@@ -7181,7 +7180,7 @@ CREATE TABLE IF NOT EXISTS `zt_vm` (
`baseImagePath` varchar(255) NOT NULL DEFAULT '',
`desc` varchar(255) NOT NULL DEFAULT '',
`heatbeat` datetime NULL,
`vnc` varchar(255) NOT NULL DEFAULT '',
`vncPort` int(10) NOT NULL DEFAULT 0,
`instance` varchar(255) NOT NULL DEFAULT '',
`eip` varchar(255) NOT NULL DEFAULT '',
`createdBy` varchar(30) NOT NULL,
@@ -7210,11 +7209,17 @@ CREATE TABLE IF NOT EXISTS `zt_baseimage` (
-- DROP TABLE IF EXISTS `zt_vmtemplate`;
CREATE TABLE IF NOT EXISTS `zt_vmtemplate` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`hostID` int(10) unsigned NOT NULL DEFAULT 0,
`templateName` varchar(255) NOT NULL DEFAULT '',
`osType` varchar(50) NOT NULL DEFAULT '',
`osCategory` varchar(50) NOT NULL DEFAULT '',
`status` varchar(50) NOT NULL DEFAULT '',
`osVersion` varchar(50) NOT NULL DEFAULT '',
`osLang` varchar(50) NOT NULL,
`cpuCoreNum` smallint(4) NOT NULL DEFAULT 0,
`memorySize` int NOT NULL DEFAULT 0,
`diskSize` int NOT NULL DEFAULT 0,
`osArch` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_browser`;
@@ -7243,7 +7248,7 @@ CREATE TABLE `zt_traincourse` (
`name` varchar(255) NOT NULL,
`status` varchar(10) NOT NULL,
`teacher` varchar(30) NOT NULL default '',
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`createdBy` varchar(255) NOT NULL,
`createdDate` date NOT NULL,
`editedBy` varchar(255) NOT NULL,
@@ -8874,7 +8879,7 @@ CREATE TABLE IF NOT EXISTS `zt_activity` (
`name` varchar(255) NOT NULL,
`optional` varchar(255) NOT NULL,
`tailorNorm` varchar(255) NOT NULL,
`content` text NOT NULL,
`content` mediumtext NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`status` varchar(30) NOT NULL,
`createdBy` varchar(30) NOT NULL,
@@ -8965,7 +8970,7 @@ CREATE TABLE IF NOT EXISTS `zt_nc` (
`auditplan` mediumint(8) NOT NULL,
`listID` mediumint(8) NOT NULL,
`title` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`type` char(30) NOT NULL,
`status` varchar(30) NOT NULL DEFAULT 'active',
`severity` char(30) NOT NULL,
@@ -8992,7 +8997,7 @@ CREATE TABLE IF NOT EXISTS `zt_zoutput` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`activity` mediumint(8) NOT NULL,
`name` varchar(255) NOT NULL,
`content` text NOT NULL,
`content` mediumtext NOT NULL,
`optional` char(20) NOT NULL,
`tailorNorm` varchar(255) NOT NULL,
`status` varchar(30) NOT NULL,
@@ -9012,7 +9017,7 @@ CREATE TABLE IF NOT EXISTS `zt_process` (
`name` varchar(255) NOT NULL,
`type` char(30) NOT NULL,
`abbr` char(30) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`status` varchar(30) NOT NULL,
`order` mediumint(9) NOT NULL,
@@ -9115,7 +9120,7 @@ CREATE TABLE IF NOT EXISTS `zt_budget` (
`subject` mediumint(8) NOT NULL,
`amount` char(30) NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` date NOT NULL,
`lastEditedBy` char(30) NOT NULL,
@@ -9137,8 +9142,8 @@ CREATE TABLE IF NOT EXISTS `zt_researchplan` (
`location` varchar(255) NOT NULL,
`team` varchar(255) NOT NULL,
`method` enum('','videoConference','interview','questionnaire','telephoneInterview') NOT NULL,
`outline` text NOT NULL,
`schedule` text NOT NULL,
`outline` mediumtext NOT NULL,
`schedule` mediumtext NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
@@ -9154,7 +9159,7 @@ CREATE TABLE IF NOT EXISTS `zt_researchreport` (
`relatedPlan` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`author` varchar(30) NOT NULL,
`content` text NOT NULL,
`content` mediumtext NOT NULL,
`customer` varchar(255) NOT NULL,
`researchObjects` varchar(255) NOT NULL,
`begin` datetime NOT NULL,
@@ -9218,7 +9223,7 @@ CREATE TABLE IF NOT EXISTS `zt_assetlib` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
@@ -9232,7 +9237,7 @@ CREATE TABLE IF NOT EXISTS `zt_meastemplate` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
`model` char(30) NOT NULL,
`name` varchar(255) NOT NULL,
`content` text NOT NULL,
`content` mediumtext NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` date NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
@@ -9453,7 +9458,7 @@ CREATE TABLE IF NOT EXISTS `zt_issue` (
`project` varchar(255) NOT NULL,
`execution` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`desc` text NOT NULL,
`desc` mediumtext NOT NULL,
`pri` char(30) NOT NULL,
`severity` char(30) NOT NULL,
`type` char(30) NOT NULL,
@@ -9499,8 +9504,8 @@ CREATE TABLE IF NOT EXISTS `zt_risk` (
`rate` char(30) NOT NULL,
`pri` char(30) NOT NULL,
`identifiedDate` date NOT NULL,
`prevention` text NOT NULL,
`remedy` text NOT NULL,
`prevention` mediumtext NOT NULL,
`remedy` mediumtext NOT NULL,
`plannedClosedDate` date NOT NULL,
`actualClosedDate` date NOT NULL,
`lib` mediumint(8) unsigned NOT NULL default 0,
@@ -9510,7 +9515,7 @@ CREATE TABLE IF NOT EXISTS `zt_risk` (
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`resolution` text NOT NULL,
`resolution` mediumtext NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`activateBy` varchar(30) NOT NULL,
`activateDate` date NOT NULL,
@@ -9548,7 +9553,7 @@ CREATE TABLE IF NOT EXISTS `zt_opportunity` (
`assignedTo` varchar(30) NOT NULL,
`assignedDate` date NOT NULL,
`approvedDate` date NOT NULL,
`prevention` text NOT NULL,
`prevention` mediumtext NOT NULL,
`plannedClosedDate` date NOT NULL,
`actualClosedDate` date NOT NULL,
`lib` mediumint(8) unsigned NOT NULL default 0,
@@ -9567,7 +9572,7 @@ CREATE TABLE IF NOT EXISTS `zt_opportunity` (
`cancelReason` char(30) NOT NULL,
`hangupedBy` varchar(30) NOT NULL,
`hangupedDate` datetime NOT NULL,
`resolution` text NOT NULL,
`resolution` mediumtext NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`resolvedDate` datetime NOT NULL,
`lastCheckedBy` varchar(30) NOT NULL,
@@ -9588,7 +9593,7 @@ CREATE TABLE IF NOT EXISTS `zt_trainplan` (
`lecturer` varchar(20) NOT NULL,
`type` enum('inside','outside') NOT NULL DEFAULT 'inside',
`status` varchar(20) NOT NULL,
`summary` text NOT NULL,
`summary` mediumtext NOT NULL,
`createdBy` char(30),
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
@@ -9603,7 +9608,7 @@ CREATE TABLE IF NOT EXISTS `zt_gapanalysis` (
`project` mediumint(8) unsigned NOT NULL,
`account` varchar(30) NOT NULL,
`role` varchar(20) NOT NULL,
`analysis` text NOT NULL,
`analysis` mediumtext NOT NULL,
`needTrain` enum('no','yes') NOT NULL DEFAULT 'no',
`createdBy` char(30),
`createdDate` datetime NOT NULL,
+192
View File
@@ -1,3 +1,195 @@
2022-03-24 16.5
修复的bug
21082 泳道被删除后再还原,泳道中的任务显示了两遍
21054 看板中删除看板后没有跳转到最近执行中
21052 产品概况页面,样式显示问题
21044 已关闭执行不支持删除
21037 瀑布项目创建阶段,创建人和负责人没有同步到团队中
21036 批量创建任务页面,左侧模块选中同上后,右侧需求对应的是其他模块的需求
21029 批量创建任务页面选择需求后无法查看需求
20977 需求详情页点击迭代,样式不正确
20976 任务列表中研发需求未显示
20975 任务看板,样式问题
20930 【瀑布项目】执行设置多个产品是报错
20923 专业研发看板中提Bug保存后弹窗未关闭
20918 计划的需求列表展示需求数据不正确
20915 专业研发看板中编辑页面样式有问题
20813 批量编辑阶段会退出编辑界面
20808 产品计划关联需求页面,点击开始按钮后取消,有报错
20807 看板项目在项目集列表中显示图标不正确
20766 不启用进度管理,卡片详情/编辑页还显示进度字段
20742 不填写用户名保存后再补充用户名登录用户没有权限
20713 升级后提Bug,有版本仍显示创建发布
20661 经典模式下,右上角显示研发综合界面
20646 卡片设置为非白色时进度应该显示为白色
20645 历史已完成的卡片进度还是0%应该处理成100%
20588 安装禅道设置账号时不填写密码点击保存可以跳转至安装成功页面
20543 提Bug选择分支或切换产品后默认选中执行
20490 权限页面上执行中老看板权限没有隐藏
20457 研发综合界面全局ID搜索显示了迅捷版内容
20396 批量提Bug切换分支和执行后版本可以选择所有版本
20111 文档执行库创建执行库后跳转项目库界面报错
20098 发布关联版本时带过来的需求不会变成已发布
19709 提Bug页面,更换所属项目,影响版本没有刷新
19698 win32一键安装包中导入jira数据页面报错
19696 国际版16.4面板右下角升级页面显示有误
19680 导入jira数据设置jira和禅道关系页面下一步和返回按钮应该显示在页面下方
19662 导入jira数据,保存成功的样式已系统的不一致
19647 导入jira数据后我近期参与的项目显示重复数据
19644 设置Jira用户页面密码没有必填项标识
19577 设置Jira与禅道数据对应关系保存提示信息样式需优化
19439 富文本类型文档没有对比功能
19382 经典管理模式下,编辑已有项目不能关联新建的产品
19315 调用接口创建、修改bug重现步骤、模块不生效
19261 解决Bug时,提示所属执行不能为空
19256 看板项目下无法创建版本
19251 通用看板中子列卡片数量超出在制品限制时左侧没有间隔
19243 专业项目看板id与通用看板id重复下,通用看板可以修改自定义高度
19238 联系人图标的边框线没闭合
19074 创建空间,切换空间类型时弹窗页面抖动
19004 子列归档时下方显示了更多菜单列
18344 php8.0,看板新建卡片时不输入预计工时,点击保存提示预计不能为负数
18269 瀑布项目下创建阶段,没有把创建者添加到阶段的团队中
18018 公司名输入代码内容,导致登录时有空白弹窗提示
18017 当用户里面有中文用户名时 , 所有搜索功能无法加载
17963 没有产品权限也没有创建产品权限点击产品库提示没有产品权限
17944 API 创建的数据 触发发信通知 邮箱里面的超链接网址拼接有问题
17943 瀑布模型下已删除任务的阶段不能创建子阶段
17668 修改区域名称为特殊字符不能正确显示特殊字符
17627 已选择的干系人再次添加时不应该显示在下拉菜单里
17415 在项目--迭代页面关闭提示框会自动跳转到执行
17396 项目集中创建项目时点击选择项目管理方式后选择项目页面没关闭
17341 经典模式下研发需求分解任务时同上模块之后相关需求联动错误
17330 提需求页面创建计划弹窗大小与其他弹窗大小不一致
17284 项目集列表页创建项目后,选择项目管理方式弹窗仍存在
17264 编辑接口库名称输入空格之后保存成功且页面显示不对
17254 在项目-Bug提Bug页面刷新回调转到测试-Bug中
17191 添加执行时有多个分支保存报错提示框显示错误
17180 经典模式下任务详情所属模块换行显示
17139 头像权限问题报错
17110 项目团队成员没有项目文档主库的权限
17062 任务看板中,表格错位
17054 chrome浏览器,调整卡片显示数量,出现更多按钮
17048 数据迁移提示,相关文案需修改
17023 项目需求下,减少添加研发需求的入口
16841 优先级名称过长导致优先级名称与Bug名称重叠了
16718 需求名称控件宽度不够
16662 创建版本库没自动列出关联的产品
16646 文档的产品库中产品显示错误
16575 编辑执行页面可以关联已过期的计划需与创建关联逻辑一致
16313 经典模式升级后必填项页面展示不正确
16299 项目集下批量编辑产品负责人下拉中的closed需去掉
16264 收起左侧模块树状图后,任务、Bug等列表页面设置图标显示有问题
16207 接口库的目录和接口没有悬浮菜单
16204 文档-产品库中编辑文档,跳转到产品-文档
16114 接口库中接口切换版本后显示错误
16102 项目看板下个别项目没有显示项目集
16004 经典模式下项目编辑页面关联产品下拉没有数据
15823 安装过甘特图插件的代码,升级到15.5以上版本项目看板报错
15554 部分文档大小不显示
15517 删除项目时项目下的执行也被删除了
15269 项目文档因权限问题显示错误
15064 项目集下拉菜单鼠标悬浮闪烁
14981 点击项目集看板中的项目无法跳到相应的项目下
14595 管理执行团队复制团队项目名称过长显示错误
14573 项目集列表进度图标显示不正确
14560 产品下拉组件的样式不一致
14363 用例库中用例批量编辑的时候左上角显示为了产品名
14233 优化和统一文档无数据时的提示文案
14134 记录工时工作内容为必填项没有标注必填
14090 执行/迭代 列表页面 ,执行/迭代 代号没有展示
14050 markdown文本框中粘贴内容后部分内容未显示
13910 执行-建任务界面,返回页面错误
13884 markdown类型文档浏览显示问题
13855 未对团队人员的可用工日和可用工时/天进行校验
13345 创建文档库界面选择分组列表显示不完整
13031 不分配模块权限,文档页面还是会显示分类按钮
12951 全部折叠按钮只能折叠当前页的数据
12790 批量执行用例后,跳转的页面需要调整
12671 创建用例页面优先级超出页面
12655 恢复默认对隐藏和显示已关闭已取消列不生效
12638 Bug编辑页面相关需求下拉超出提Bug页面
12617 列表设置简单表格,在列表最下面才能滚动
12475 使用功能点估算时任务列表还是显示为工时
12419 关闭的项目中还可以创建任务
12390 编辑修改bug的解决版本后,在之前版本的解决bug列表中还会显示
12313 通过首页最新动态点击查看文档,文档详情页面无内容
12086 内禅项目需求关联需求页面中,全选操作会和ID排序同时进行
11997 批量提bug时多项录入功能导致页面卡住
11983 设置项目团队后无法访问项目
11784 项目集的投入人员列表中出现了人员名称为空的数据
11673 用户需求显示了阶段字段
11668 需求详情页历史记录中关联到的迭代无法点击
11323 产品发布详情中,遗留的Bug列表出现折行显示
11322 产品发布中,打开具体的发布详情页面,完成的研发需求列表需求出现折行显示
11138 任务列表状态字段内容显示不全
11009 多平台子需求模块无法正常编辑
2022-03-16 16.5.beta1
完成的需求
50241 增加专业研发看板中需求/任务/Bug删除功能
50240 增加Scrum看板中需求/任务/Bug删除功能
49889 提需求页面需求类别统一显示为需求类型
49888 泳道组中有多个共享列的泳道时,创建页面中增加所属泳道的选择
49886 计划的需求列表中提需求后返回计划的需求列表
49885 完善飞书工作消息通知添加Webhook之后,绑定用户页面,等待近一分钟后才打开页面的功能。
49883 单个计划增加关闭操作
49882 计划列表中子计划前增加标识
49881 计划列表中计划名称字段最小宽度250px
49880 计划富文本框中的格式在计划列表描述中格式有误
49696 专业研发看板中任务泳道实现导入Bug功能
49695 专业研发看板中实现任务的更多操作功能
49694 专业研发看板中实现Bug的更多操作功能
49693 专业研发看板中实现需求的更多操作功能
49692 设置空间页面增加空间类型的调整
49318 从用例库导入用例,确认页面分支平台栏默认同上
49303 计划未开启分支功能时,可根据浏览器高度自适应显示看板高度
49302 计划列表增加批量调整状态功能
49301 经典模式下项目列表标签后显示项目数量
49299 执行关联了多个产品时,在所有产品条件下不提供批量创建需求功能
49298 看板关联了多个产品时,在批量提需求页面中提供产品的选择功能
49297 专业研发看板在批量提交Bug页面的多产品时,提供产品的选择功能
49296 添加需求页面增加所属父需求的下拉选项
49295 系统头像中无头像时显示具体的人名
49294 已提交评审的需求在详情页中增加撤销评审按钮
49293 调整需求变更后消息通知的范围
49292 项目选择重新定义权限时创建者和负责人取系统权限
49289 计划详情信息中增加计划状态字段
49286 可以将保存的搜索条件设置为公共搜索条件
49285 通过编号搜索时可以指定多个ID进行检索
49284 搜索中增加加激活日期的条件
49283 列表中优先级P鼠标悬浮时显示为优先级
49282 执行看板中对延期执行增加已延期标识
49281 批量创建需求页面由谁评审可以默认选择同上
49280 项目看板中对延期项目增加已延期标识
修复 Bug
19646 导入的Jira数据查看执行的研发需求、设置报错
19639 导入的Jira数据任务下没有显示相关的附件
19614 从文件导入Jira数据时,不导入文件点击下一步后无法继续进行
19592 编辑需求概念弹窗保存成功提示信息样式需调整下
19565 不清空tmp下的jirafile重新导入新的数据库会有代码报错
19557 创建产品报错
19506 提交测试页面中相关测试报告只能选择当前版本下的测试报告
19471 项目集添加干系人页面显示不正确
19445 待处理下鼠标悬浮Bug标题title显示不全
19408 多分支产品导出用例模板错误
19389 看板项目中的看板新增区域选择复制自定义的区域报错
19383 集成GitLab后只能同步到1000个项目
19335 php74下进入GitLab项目列表报错
19327 研发看板下按计划关联需求页面“迭代”文案不合理
19323 用户名包含特殊字符,例如 . ,更换头像后,点保存不自动跳转
19307 项目左上角下拉框内已关闭的看板项目标题 展示不正确
19306 地盘日程添加任务、bug待办点击完成界面报错
19255 看板创建Bug显示所属执行
19249 需求概念设置页面样式不正确
19161 归档功能默认不启用
19137 无法设置禅道主题
18741 待评审需求,编辑页面没有带入关闭原因
18305 地盘创建Bug类型的日程开始待办提示Todo
17338 无权限提示,显示为英文
17336 项目关联研发需求时显示已关联的需求
17312 保存和返回按钮没表单居中
2022-02-15 16.4
完成的需求
30526 实现JIRA数据导入到禅道功能
@@ -0,0 +1,3 @@
<?php
include $app->getExtensionRoot() . '/biz/attend/ext/view/stat.oa.html.hook.php';
?>
@@ -263,3 +263,35 @@ $lang->createObjects['execution'] = 'TaskKanban';
$lang->createObjects['kanban'] = 'Kanban';
$lang->createIcons['execution'] = 'kanban';
/* Xuan */
global $config;
if(isset($config->xuanxuan) && strpos($config->visions, ',rnd,') === false)
{
$lang->xuanxuan = new stdclass();
$lang->admin->menu->xuanxuan = array('link' => 'Chat|admin|xuanxuan', 'subModule' => 'client,setting');
$lang->admin->menuOrder[6] = 'xuanxuan';
$lang->admin->menu->xuanxuan['subMenu'] = new stdclass();
$lang->admin->menu->xuanxuan['subMenu']->index = array('link' => 'Home|admin|xuanxuan');
$lang->admin->menu->xuanxuan['subMenu']->setting = array('link' => 'Parameter|setting|xuanxuan');
$lang->admin->menu->xuanxuan['subMenu']->update = array('link' => 'Update|client|browse', 'subModule' => 'client');
$lang->admin->menu->xuanxuan['menuOrder'][0] = 'index';
$lang->admin->menu->xuanxuan['menuOrder'][5] = 'setting';
$lang->admin->menu->xuanxuan['menuOrder'][10] = 'update';
if($config->edition != 'open')
{
$lang->admin->menu->xuanxuan['subModule'] = 'client,setting,conference';
$lang->admin->menu->xuanxuan['subMenu']->conference = array('link' => 'Conference|conference|admin');
$lang->admin->menu->xuanxuan['menuOrder'][7] = 'conference';
$lang->navGroup->conference = 'admin';
}
$lang->navGroup->im = 'admin';
$lang->navGroup->setting = 'admin';
$lang->navGroup->client = 'admin';
$lang->confirmDelete = 'Do you want to delete it?';
}
@@ -263,3 +263,35 @@ $lang->createObjects['execution'] = '任务看板';
$lang->createObjects['kanban'] = '通用看板';
$lang->createIcons['execution'] = 'kanban';
/* Xuan */
global $config;
if(isset($config->xuanxuan) && strpos($config->visions, ',rnd,') === false)
{
$lang->xuanxuan = new stdclass();
$lang->admin->menu->xuanxuan = array('link' => '聊天|admin|xuanxuan', 'subModule' => 'client,setting');
$lang->admin->menuOrder[6] = 'xuanxuan';
$lang->admin->menu->xuanxuan['subMenu'] = new stdclass();
$lang->admin->menu->xuanxuan['subMenu']->index = array('link' => '首页|admin|xuanxuan');
$lang->admin->menu->xuanxuan['subMenu']->setting = array('link' => '参数|setting|xuanxuan');
$lang->admin->menu->xuanxuan['subMenu']->update = array('link' => '更新|client|browse', 'subModule' => 'client');
$lang->admin->menu->xuanxuan['menuOrder'][0] = 'index';
$lang->admin->menu->xuanxuan['menuOrder'][5] = 'setting';
$lang->admin->menu->xuanxuan['menuOrder'][10] = 'update';
if($config->edition != 'open')
{
$lang->admin->menu->xuanxuan['subModule'] = 'client,setting,conference';
$lang->admin->menu->xuanxuan['subMenu']->conference = array('link' => '音视频|conference|admin');
$lang->admin->menu->xuanxuan['menuOrder'][7] = 'conference';
$lang->navGroup->conference = 'admin';
}
$lang->navGroup->im = 'admin';
$lang->navGroup->setting = 'admin';
$lang->navGroup->client = 'admin';
$lang->confirmDelete = '您确定要执行删除操作吗?';
}
@@ -23,4 +23,5 @@ $lang->execution->icons['grouptask'] = 'sitemap';
$lang->execution->aclList['private'] = "Private (Accessible to team members and project leaders)";
$lang->execution->common = 'Project Execution';
$lang->execution->common = 'Project Execution';
$lang->execution->gantt = 'Gantt Chart';
@@ -24,4 +24,4 @@ $lang->execution->icons['grouptask'] = 'sitemap';
$lang->execution->aclList['private'] = "私有(团队成员和项目负责人可访问)";
$lang->execution->common = '项目看板';
$lang->execution->common = '项目看板';
+13 -6
View File
@@ -127,13 +127,20 @@ public function getTRActions($currentMethod)
foreach($subMenu as $key => $value)
{
$tmpValue = explode('|', $value['link']);
$subMenu->{$key}['name'] = $tmpValue[0];
$subMenu->{$key}['module'] = $tmpValue[1];
$subMenu->{$key}['method'] = $tmpValue[2];
$subMenu->{$key}['vars'] = $tmpValue[3];
if(common::hasPriv('execution', $key))
{
$tmpValue = explode('|', $value['link']);
$subMenu->{$key}['name'] = $tmpValue[0];
$subMenu->{$key}['module'] = $tmpValue[1];
$subMenu->{$key}['method'] = $tmpValue[2];
$subMenu->{$key}['vars'] = $tmpValue[3];
}
else
{
unset($subMenu->$key);
}
}
$TRActions = '';
$TRActions .= "<div class='btn-group dropdown'>";
$TRActions .= html::a("javascript:;", "<i class='icon icon-" . $this->lang->execution->icons[$currentMethod]."'> </i>" . $subMenu->{$currentMethod}['name'] . " <span class='caret'></span>", '', "class='btn btn-link' data-toggle='dropdown'");
+31 -1
View File
@@ -1,4 +1,7 @@
<?php
global $config;
/* Module order. */
$lang->moduleOrder = array();
@@ -35,8 +38,27 @@ $lang->moduleOrder[200] = 'backup';
$lang->moduleOrder[205] = 'cron';
$lang->moduleOrder[215] = 'message';
/* Backup xuan related stuff. */
if(isset($config->xuanxuan))
{
$imResource = $lang->resource->im;
$clientResource = $lang->resource->client;
$settingResource = $lang->resource->setting;
}
/* Reset resource. */
$lang->resource = new stdclass();
/* Reapply xuan stuff. */
if(isset($config->xuanxuan))
{
$lang->resource->im = $imResource;
$lang->resource->client = $clientResource;
$lang->resource->setting = $settingResource;
$lang->admin->methodOrder[26] = 'xuanxuan';
$lang->setting->methodOrder[26] = 'xuanxuan';
}
/* Index module. */
$lang->resource->index = new stdclass();
$lang->resource->index->index = 'index';
@@ -127,7 +149,6 @@ $lang->personnel->methodOrder[15] = 'whitelist';
$lang->personnel->methodOrder[20] = 'addWhitelist';
$lang->personnel->methodOrder[25] = 'unbindWhitelist';
global $config;
if($config->systemMode == 'new')
{
$lang->resource->my->project = 'project';
@@ -444,6 +465,8 @@ $lang->resource->execution->unbindWhitelist = 'unbindWhitelist';
//$lang->resource->execution->storyEstimate = 'storyEstimate';
$lang->resource->execution->kanban = 'kanban';
//if($config->systemMode == 'classic') $lang->resource->project->list = 'list';
if($config->edition != 'open') $lang->resource->execution->gantt = 'ganttchart';
if($config->edition != 'open') $lang->resource->execution->calendar = 'calendar';
//$lang->execution->methodOrder[0] = 'index';
//if($config->systemMode == 'classic') $lang->project->methodOrder[1] = 'list';
@@ -498,6 +521,8 @@ $lang->execution->methodOrder[250] = 'addWhitelist';
$lang->execution->methodOrder[255] = 'unbindWhitelist';
$lang->execution->methodOrder[260] = 'storyEstimate';
$lang->execution->methodOrder[270] = 'kanban';
$lang->execution->methodOrder[280] = 'gantt';
$lang->execution->methodOrder[285] = 'calendar';
/* Task. */
$lang->resource->task = new stdclass();
@@ -791,6 +816,11 @@ $lang->admin->methodOrder[20] = 'sso';
$lang->admin->methodOrder[25] = 'register';
$lang->admin->methodOrder[30] = 'ztCompany';
if(isset($config->xuanxuan))
{
$lang->resource->admin->xuanxuan = 'xuanxuan';
}
/* Extension. */
$lang->resource->extension = new stdclass();
$lang->resource->extension->browse = 'browseAction';
@@ -0,0 +1,19 @@
<?php if($config->edition == 'biz' && $config->vision == 'lite' && trim($config->visions, ',') != 'lite'):?>
<script>
$(function()
{
$('#globalBarLogo a').eq(1).attr('title', '<?php echo str_replace('biz', $lang->bizName . ' ', $config->version);?>');
$('#globalBarLogo a .version').html('<?php echo ' ' . str_replace('biz', $lang->bizName . ' ', $config->version);?>');
$('#globalBarLogo a .upgrade').html('<?php echo $lang->maxName;?>');
})
</script>
<?php elseif($config->edition == 'max' && $config->vision == 'lite' && trim($config->visions, ',') != 'lite'):?>
<script>
$(function()
{
$('#globalBarLogo a').eq(1).attr('title', '<?php echo str_replace('max', $lang->maxName . ' ', $config->version);?>');
$('#globalBarLogo a .version').html('<?php echo ' ' . str_replace('max', $lang->maxName . ' ', $config->version);?>');
$('#globalBarLogo a .upgrade').html('<?php echo $lang->upgrade->common;?>');
})
</script>
<?php endif;?>
+1 -1
View File
@@ -19,7 +19,7 @@ Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>Easy
Twitter: <a href='https://twitter.com/ZentaoA' target='_blank'>ZenTao Lite</a>
You are installing ZenTao <strong class='text-danger'>%s</strong>.
EOT;
$lang->install->successLabel = "<p>You have installed ZenTao Lite %s.</p>";
@@ -0,0 +1,3 @@
<script>
$('#headerActions').css("right", '210px');
</script>
@@ -1,4 +1,3 @@
<script>
$('#zentaoLinks > .row > .col-sm-2').removeClass('col-sm-2').addClass('col-sm-4');
$('#mainContent tbody > tr:first-child > td.text-center > h4').text('<?php printf($lang->misc->zentao->version, $config->liteVersion);?>');
</script>
@@ -37,8 +37,24 @@
</div>
<?php else:?>
<div class='kanban-cards'>
<?php
$kanbanview = 'kanban';
if($this->cookie->kanbanview) $kanbanview = $this->cookie->kanbanview;
if(!common::hasPriv('execution', $kanbanview))
{
foreach (explode('|', 'kanban|task|calendar|gantt|tree|grouptask') as $view)
{
if(common::hasPriv('execution', $view))
{
$kanbanview = $view;
break;
}
}
}
?>
<?php foreach($kanbanList as $index => $kanban):?>
<div id="kanban-<?php echo $kanban->id;?>" class='kanban-card col' data-url='<?php echo $this->createLink('execution', $this->cookie->kanbanview ? $this->cookie->kanbanview : 'kanban', "kanbanID=$kanban->id");?>'>
<div id="kanban-<?php echo $kanban->id;?>" class='kanban-card col' data-url='<?php echo $this->createLink('execution', $kanbanview, "kanbanID=$kanban->id");?>'>
<div class="panel">
<div class="panel-heading">
<span class="label kanban-status-<?php echo $kanban->status;?>"><?php echo zget($lang->execution->statusList, $kanban->status);?></span>
@@ -252,7 +252,7 @@ $(function()
{
for(var num = 1; num <= 10; num++)
{
$('#lane' + num).replaceWith(data.replace('lane1', 'lane' + num));
$('#lane' + num).replaceWith(data.replace('lane1', 'lane' + num).replace('lane[1]', 'lane[' + num + ']'));
$('#lane' + num + '_chosen').remove();
$('#lane' + num).chosen();
}
+1 -1
View File
@@ -337,7 +337,7 @@
<?php js::set('executionID', $execution->id);?>
<?php if(isonlybody()):?>
<style>
.body-modal .main-header {padding-right: 0px; z-index: 1100;}
.body-modal .main-header {padding-right: 0px; z-index: 1000;}
.btn-toolbar > .dropdown {margin: 0px;}
</style>
<?php $html = '<div class="divider"></div><button id="closeModal" type="button" class="btn btn-link" data-dismiss="modal"><i class="icon icon-close"></i></button>';?>
@@ -1,6 +1,7 @@
<?php
$lang->todo->typeList['task'] = '任务';
if($this->config->visions == ',lite,') unset($lang->todo->typeList['feedback']);
unset($lang->todo->typeList['bug']);
unset($lang->todo->typeList['testtask']);
unset($lang->todo->typeList['review']);
+1
Submodule extension/qucheng added at 14b5630326
+4 -4
View File
@@ -153,16 +153,16 @@ class helper extends baseHelper
* @access public
* @return string
*/
static public function createLink($moduleName, $methodName = 'index', $vars = '', $viewType = '', $onlyBody = false)
static public function createLink($moduleName, $methodName = 'index', $vars = '', $viewType = 'json', $onlyBody = false)
{
global $config;
$link = parent::createLink($moduleName, $methodName, $vars, 'html');
$link = parent::createLink($moduleName, $methodName, $vars, $viewType);
$pos = strpos($link, '.php');
/* The requestTypes are: GET, PATH_INFO2, PATH_INFO */
if($config->requestType == 'GET')
{
$link = '/index' . substr($link, $pos);
$link = $config->webRoot . 'index' . substr($link, $pos);
}
elseif($config->requestType == 'PATH_INFO2')
{
@@ -204,7 +204,7 @@ function formatTime($time, $format = '')
/**
* Fix for session error.
*
* @param int $class
* @param int $class
* @access protected
* @return void
*/
+1 -1
View File
@@ -2076,7 +2076,7 @@ class baseRouter
if($type != 'fetch')
{
/* 分割URI。 Spit the URI. */
$items = explode($this->config->requestFix, $this->URI);
$items = explode($this->config->requestFix, (string)$this->URI);
$itemCount = count($items);
/**
@@ -1,5 +1,4 @@
<?php
#
#
# Parsedown Extra Plugin
+4
View File
@@ -261,6 +261,7 @@ $lang->action->label->changestatus = 'changed status';
$lang->action->label->marked = 'marked';
$lang->action->label->linked2execution = "linked to {$lang->executionCommon}";
$lang->action->label->unlinkedfromexecution = "unlinked from {$lang->executionCommon}";
$lang->action->label->linked2kanban = 'linked to kanban';
$lang->action->label->linked2project = "linked to project";
$lang->action->label->unlinkedfromproject = "unlinked from project";
$lang->action->label->unlinkedfrombuild = "unlinked Build ";
@@ -422,6 +423,7 @@ $lang->action->dynamicAction->story['undeleted'] = 'Restore Story';
$lang->action->dynamicAction->story['hidden'] = 'Hide Story';
$lang->action->dynamicAction->story['linked2execution'] = "Link Story";
$lang->action->dynamicAction->story['unlinkedfromexecution'] = "Unlink Story";
$lang->action->dynamicAction->story['linked2kanban'] = "Link Story";
$lang->action->dynamicAction->story['estimated'] = "Estimate $lang->SRCommon";
$lang->action->dynamicAction->execution['opened'] = 'Create ' . $lang->executionCommon;
@@ -709,6 +711,7 @@ $lang->action->search->label['linked2project'] = $lang->action->label->li
$lang->action->search->label['unlinkedfromproject'] = $lang->action->label->unlinkedfromproject;
$lang->action->search->label['linked2execution'] = $lang->action->label->linked2execution;
$lang->action->search->label['unlinkedfromexecution'] = $lang->action->label->unlinkedfromexecution;
$lang->action->search->label['linked2kanban'] = $lang->action->label->linked2kanban;
$lang->action->search->label['started'] = $lang->action->label->started;
$lang->action->search->label['restarted'] = $lang->action->label->restarted;
$lang->action->search->label['recordestimate'] = $lang->action->label->recordestimate;
@@ -790,6 +793,7 @@ $lang->action->apiTitle->changestatus = 'Changed status';
$lang->action->apiTitle->marked = 'Marked';
$lang->action->apiTitle->linked2execution = "Linked to {$lang->executionCommon}";
$lang->action->apiTitle->unlinkedfromexecution = "Unlinked from {$lang->executionCommon}";
$lang->action->apiTitle->linked2kanban = 'Linked to Kanban';
$lang->action->apiTitle->linked2project = "Linked to project";
$lang->action->apiTitle->unlinkedfromproject = "Unlinked from project";
$lang->action->apiTitle->unlinkedfrombuild = "Unlinked from build";
+4
View File
@@ -261,6 +261,7 @@ $lang->action->label->changestatus = '修改状态';
$lang->action->label->marked = '编辑了';
$lang->action->label->linked2execution = "关联{$lang->executionCommon}";
$lang->action->label->unlinkedfromexecution = "移除{$lang->executionCommon}";
$lang->action->label->linked2kanban = '关联看板';
$lang->action->label->linked2project = "关联项目";
$lang->action->label->unlinkedfromproject = "移除项目";
$lang->action->label->unlinkedfrombuild = "移除版本";
@@ -422,6 +423,7 @@ $lang->action->dynamicAction->story['undeleted'] = "还原{$lang->SR
$lang->action->dynamicAction->story['hidden'] = "隐藏{$lang->SRCommon}";
$lang->action->dynamicAction->story['linked2execution'] = "关联$lang->SRCommon";
$lang->action->dynamicAction->story['unlinkedfromexecution'] = "移除$lang->SRCommon";
$lang->action->dynamicAction->story['linked2kanban'] = "关联$lang->SRCommon";
$lang->action->dynamicAction->story['estimated'] = "估算$lang->SRCommon";
$lang->action->dynamicAction->execution['opened'] = '创建' . $lang->executionCommon;
@@ -710,6 +712,7 @@ $lang->action->search->label['linked2project'] = $lang->action->label->li
$lang->action->search->label['unlinkedfromproject'] = $lang->action->label->unlinkedfromproject;
$lang->action->search->label['linked2execution'] = $lang->action->label->linked2execution;
$lang->action->search->label['unlinkedfromexecution'] = $lang->action->label->unlinkedfromexecution;
$lang->action->search->label['linked2kanban'] = $lang->action->label->linked2kanban;
$lang->action->search->label['started'] = $lang->action->label->started;
$lang->action->search->label['restarted'] = $lang->action->label->restarted;
$lang->action->search->label['recordestimate'] = $lang->action->label->recordestimate;
@@ -791,6 +794,7 @@ $lang->action->apiTitle->changestatus = '修改状态';
$lang->action->apiTitle->marked = '编辑';
$lang->action->apiTitle->linked2execution = "关联{$lang->executionCommon}";
$lang->action->apiTitle->unlinkedfromexecution = "移除{$lang->executionCommon}";
$lang->action->apiTitle->linked2kanban = '关联看板';
$lang->action->apiTitle->linked2project = "关联项目";
$lang->action->apiTitle->unlinkedfromproject = "移除项目";
$lang->action->apiTitle->unlinkedfrombuild = "移除版本";
+7 -5
View File
@@ -289,7 +289,7 @@ class actionModel extends model
}
if($actionType == 'unlinkedfromproject' or $actionType == 'linked2project') $record['project'] = (int)$extra ;
if($actionType == 'unlinkedfromexecution' or $actionType == 'linked2execution') $record['execution'] = (int)$extra;
if(in_array($actionType, array('unlinkedfromexecution', 'linked2execution', 'linked2kanban'))) $record['execution'] = (int)$extra;
if($record)
{
@@ -351,7 +351,7 @@ class actionModel extends model
{
$action->actor = $commiters[$action->actor];
}
elseif($actionName == 'linked2execution')
elseif($actionName == 'linked2execution' or $actionName == 'linked2kanban')
{
$execution = $this->dao->select('name,type')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch();
$name = $execution->name;
@@ -917,6 +917,8 @@ class actionModel extends model
->beginIF($docs and !$this->app->user->admin)->andWhere("IF(objectType != 'doc' || (objectType = 'doc' && (action = 'approved' || action = 'removed')), '1=1', objectID " . helper::dbIN($docs) . ")")->fi()
->beginIF($libs and !$this->app->user->admin)->andWhere("IF(objectType != 'doclib', '1=1', objectID " . helper::dbIN(array_keys($libs)) . ') ')->fi()
->beginIF($actionCondition)->andWhere("($actionCondition)")->fi()
/* Filter out client login/logout actions. */
->andWhere('action')->notin('disconnectxuanxuan,loginxuanxuan')
->orderBy($orderBy)
->page($pager)
->fetchAll();
@@ -1008,13 +1010,13 @@ class actionModel extends model
$actionQuery = str_replace("`product` = '$productID'", "`product` LIKE '%,$productID,%'", $actionQuery);
if($date) $actionQuery = "($actionQuery) AND " . ('date' . ($direction == 'next' ? '<' : '>') . "'{$date}'");
/* If this vision is lite, delete product actions. */
if($this->config->vision == 'lite') $actionQuery .= " AND objectType != 'product'";
$actionQuery .= " AND vision = '" . $this->config->vision . "'";
$actions = $this->getBySQL($actionQuery, $orderBy, $pager);
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'action');
if(!$actions) return array();
return $this->transformActions($actions);
+1 -1
View File
@@ -23,7 +23,7 @@
<h2>
<?php
$versionName = $config->version;
if($config->vision == 'lite') $versionName = $lang->liteName . $config->liteVersion;
if(trim($config->visions, ',') == 'lite') $versionName = $lang->liteName . $config->liteVersion;
printf($lang->admin->info->version, $versionName);
if($bind) echo sprintf($lang->admin->info->account, '<span class="red">' . $account . '</span>');
echo $lang->admin->info->links;
+2
View File
@@ -1,2 +1,4 @@
.c-date {width: 150px;}
.c-actions {width: 60px;}
tbody tr td {white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
+2 -2
View File
@@ -233,9 +233,9 @@ try {
</select>
</td>
<td class="w-80px">
<div class="checkbox">
<div class="checkbox-primary">
<input type="checkbox" v-model="value.required">
<label>
<input type="checkbox" v-model="value.required">
</label>
</div>
</td>
+1 -1
View File
@@ -144,7 +144,7 @@
</table>
<?php endif;?>
<?php if($api->responseExample):?>
<h3><?php echo $lang->api->responseExample;?></h3>
<h3 class='title'><?php echo $lang->api->responseExample;?></h3>
<pre><code><?php echo $api->responseExample;?></code></pre>
<?php endif;?>
</div>
+6 -8
View File
@@ -130,10 +130,9 @@ js::set('struct_paramsType', $lang->struct->paramsType);
<input type="text" placeholder="<?php echo $lang->struct->field;?>" autocomplete="off" class="form-control" v-model="item.field">
</td>
<td class="w-50px">
<div class="checkbox">
<label>
<input type="checkbox" v-model="item.required">
</label>
<div class="checkbox-primary">
<input type="checkbox" v-model="item.required">
<label></label>
</div>
</td>
<td class="w-500px">
@@ -165,10 +164,9 @@ js::set('struct_paramsType', $lang->struct->paramsType);
<input type="text" placeholder="<?php echo $lang->struct->field;?>" autocomplete="off" class="form-control" v-model="item.field">
</td>
<td class="w-50px">
<div class="checkbox">
<label>
<input type="checkbox" v-model="item.required">
</label>
<div class="checkbox-primary">
<input type="checkbox" v-model="item.required">
<label></label>
</div>
</td>
<td class="w-500px">
+6 -6
View File
@@ -125,10 +125,9 @@ js::set('api', $api);
<input type="text" placeholder="<?php echo $lang->struct->field;?>" autocomplete="off" class="form-control" v-model="item.field">
</td>
<td class="w-50px">
<div class="checkbox">
<label>
<input type="checkbox" v-model="item.required">
</label>
<div class="checkbox-primary">
<input type="checkbox" v-model="item.required">
<label></label>
</div>
</td>
<td class="w-500px">
@@ -160,8 +159,9 @@ js::set('api', $api);
<input type="text" placeholder="<?php echo $lang->struct->field;?>" autocomplete="off" class="form-control" v-model="queryP[key].field">
</td>
<td class="w-50px">
<div class="checkbox">
<label><input type="checkbox" v-model="item.required"></label>
<div class="checkbox-primary">
<input type="checkbox" v-model="item.required">
<label></label>
</div>
</td>
<td class="w-500px">
+1 -1
View File
@@ -1822,7 +1822,7 @@ class block extends control
/* load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 3, 1);
$this->view->projects = $this->loadModel('project')->getInfoList('all', 'id_desc', $pager);
$this->view->projects = $this->loadModel('project')->getInfoList('all', 'id_desc', $pager, 1);
}
/**
+20 -1
View File
@@ -107,7 +107,25 @@ $lang->block->spent = 'Has Been Spent';
$lang->block->budget = 'Budget';
$lang->block->left = 'Remain';
$lang->block->default['waterfall']['project']['3']['title'] = 'Plan Gantt Chart';
$lang->block->titleList['flowchart'] = 'Flow Chart';
$lang->block->titleList['statistic'] = 'Statistic';
$lang->block->titleList['recentproject'] = 'Recent Project';
$lang->block->titleList['assigntome'] = 'Assign to me';
$lang->block->titleList['projectteam'] = 'Project manpower input';
$lang->block->titleList['project'] = 'Project List';
$lang->block->titleList['dynamic'] = 'Dynamic';
$lang->block->titleList['list'] = 'Todo List';
$lang->block->titleList['contribute'] = 'Contribute';
$lang->block->titleList['scrumoverview'] = 'Scrumoverview';
$lang->block->titleList['scrumtest'] = 'Scrum Test';
$lang->block->titleList['scrumlist'] = 'Scrum List';
$lang->block->titleList['sprint'] = 'Sprint';
$lang->block->titleList['projectdynamic'] = 'Project Dynamic';
$lang->block->titleList['bug'] = 'Bug';
$lang->block->titleList['case'] = 'Case';
$lang->block->titleList['testtask'] = 'Test Task';
$lang->block->default['waterfall']['project']['3']['title'] = "Plan Gantt Chart";
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
@@ -144,6 +162,7 @@ $lang->block->default['scrum']['project']['4']['grid'] = 4;
$lang->block->default['scrum']['project']['5']['title'] = 'Dynamic';
$lang->block->default['scrum']['project']['5']['block'] = 'projectdynamic';
$lang->block->default['scrum']['project']['5']['grid'] = 4;
$lang->block->default['kanban'] = $lang->block->default['scrum'];
$lang->block->default['product']['1']['title'] = $lang->productCommon . ' Report';
$lang->block->default['product']['1']['block'] = 'statistic';
@@ -69,8 +69,8 @@ $(function()
var isPrev = $(this).is('.prev');
var $activeItem = $nav.children('.active');
var $next = $activeItem[isPrev ? 'prev' : 'next']('li:not(.switch-icon)');
if ($next.length) $next.find('a').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a').trigger('click');
if ($next.length) $next.find('a[data-toggle="tab"]').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a[data-toggle="tab"]').trigger('click');
e.preventDefault();
});
+2 -1
View File
@@ -3,7 +3,7 @@
<?php $idx = 0; ?>
<div class='row row-<?php echo $flowName?>'>
<?php foreach ($flow as $flowItem):?>
<div class='flow-item flow-item-<?php echo $idx++ ?>'><div title='<?php echo $flowItem ?>'><?php echo $flowItem ?></div></div>
<div class='flow-item flow-item-<?php echo $idx++ ?>'><div title='<?php echo $flowItem ?>'><span><?php echo $flowItem ?></span></div></div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
@@ -16,6 +16,7 @@
.ie-8 .flow-item > div:before {display: none}
.flow-item > div:before {border-left-color: #fff; z-index: 1}
.flow-item > div:after {left: auto; right: -10px; z-index: 2}
.flow-item > div > span {display: flow-root; overflow: hidden;}
.ie-8 .flow-item > div {margin-right: 10px}
.flow-item-0 > div {color: #838A9D; font-weight: bold; padding-left: 0;}
.flow-item-0 > div:before {display: none}
@@ -29,7 +29,7 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po
.product-info .type-label {font-size: 12px; overflow: visible; text-overflow: ellipsis; white-space: nowrap;}
.product-info .type-value {font-size: 14px;}
.product-info .type-value > strong {font-size: 20px; color: #3C4353;}
.product-info .actions {position: absolute; left: 10px; top: 14px;}
.product-info .actions {position: absolute; right: 90px; top: 14px;}
.block-statistic .panel-body {padding-top: 0;}
.block-statistic .panel-body {padding-top: 0;}
.block-statistic .tile {margin-bottom: 30px;}
@@ -84,8 +84,8 @@ $(function()
var isPrev = $(this).is('.prev');
var $activeItem = $nav.children('.active');
var $next = $activeItem[isPrev ? 'prev' : 'next']('li:not(.switch-icon)');
if ($next.length) $next.find('a').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a').trigger('click');
if ($next.length) $next.find('a[data-toggle="tab"]').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a[data-toggle="tab"]').trigger('click');
e.preventDefault();
});
@@ -97,8 +97,8 @@ $(function()
var isPrev = $(this).is('.prev');
var $activeItem = $nav.children('.active');
var $next = $activeItem[isPrev ? 'prev' : 'next']('li:not(.switch-icon)');
if ($next.length) $next.find('a').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a').trigger('click');
if ($next.length) $next.find('a[data-toggle="tab"]').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a[data-toggle="tab"]').trigger('click');
e.preventDefault();
});
+2 -2
View File
@@ -69,8 +69,8 @@ $(function()
var isPrev = $(this).is('.prev');
var $activeItem = $nav.children('.active');
var $next = $activeItem[isPrev ? 'prev' : 'next']('li:not(.switch-icon)');
if ($next.length) $next.find('a').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a').trigger('click');
if ($next.length) $next.find('a[data-toggle="tab"]').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a[data-toggle="tab"]').trigger('click');
e.preventDefault();
});
@@ -44,8 +44,10 @@
<div class='col'>
<div class='panel-content'>
<div class='panel-heading not-move-handler'>
<?php $labelClass = $project->model == 'waterfall' ? 'label-warning' : 'label-info';?>
<?php if($config->systemMode == 'new'):?>
<?php $labelClass = $project->model == 'waterfall' ? 'label-warning' : 'label-info';?>
<span class='project-type-label label <?php echo $labelClass;?> label-outline'><?php echo $lang->project->{$project->model};?></span>
<?php endif;?>
<strong class='project-name' title='<?php echo $project->name;?>'> <?php echo html::a($viewLink, $project->name);?> </strong>
<nav class='panel-actions nav nav-default'>
<li class='dropdown'>
+2 -2
View File
@@ -22,7 +22,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
.block-todoes .todoes > li {position: relative; padding: 5px 10px 5px 35px; list-style: none; white-space:nowrap; overflow: auto; overflow-x:hidden;}
.block-todoes .todoes > li:hover {background-color: #e9f2fb;}
.block-todoes .todo-title {padding: 5px 15px 5px 5px;}
.titleBox {width: 700px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;}
.titleBox {max-width: 700px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;}
.block-todoes .todo-pri {margin: 0 5px;}
.block-todoes .todo-time {display: inline-block; padding: 0 5px; font-size: 12px; color: #8e939a; width: 95px;}
.block-todoes .todo-check {position: absolute; top: 5px; left: 10px; display: block; width: 20px; height: 20px; font-size: 20px; color: transparent; cursor: pointer; background: #fff; border: 2px solid #eee; border-radius: 50%;}
@@ -97,7 +97,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
?>
<li data-id='<?php echo $todo->id?>' class='titleBox'>
<span class="todo-check icon icon-check-circle"></span>
<a href="<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink);?>" class='iframe' data-toggle='modal' <?php echo $appid?>>
<a href="<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink);?>" class='iframe' data-width='1000px' data-toggle='modal' <?php echo $appid?>>
<?php if ($todo->date == '2030-01-01') :?>
<span class="todo-time"><?php echo $lang->todo->periods['future'] ?></span>
<?php else:?>
+12 -11
View File
@@ -40,7 +40,7 @@
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->branch->noData;?></span>
<?php if($canCreate) echo html::a($this->createLink('branch', 'create', "productID=$productID", '', true), "<i class='icon icon-plus'></i> " . $lang->branch->create, '', "class='btn btn-info iframe'");?>
<?php if($canCreate and $browseType != 'closed') echo html::a($this->createLink('branch', 'create', "productID=$productID", '', true), "<i class='icon icon-plus'></i> " . $lang->branch->create, '', "class='btn btn-info iframe'");?>
</p>
</div>
<?php else:?>
@@ -82,17 +82,18 @@
<td class='c-name flex branchName' title='<?php echo $branch->name;?>'>
<span class="text-ellipsis"><?php echo $branch->name;?>&nbsp;</span>
<?php
if($branch->default)
{
echo '<span class="label label-primary label-badge">' . $lang->branch->default . '</span>';
}
elseif($branch->status == 'active')
{
$setDefaultLink = helper::createLink('branch', 'setDefault', "productID=$productID&branchID=$branch->id", '', true);
$setDefaultHtml = html::a($setDefaultLink, "<span><i class='icon icon-hand-right'></i> {$lang->branch->setDefault}</span>", 'hiddenwin', "class='btn btn-icon-left btn-sm setDefault hidden'");
/* Fix bug#17342,由于默认分支的后续功能没做,暂时隐藏设置默认分支的功能 */
//if($branch->default)
//{
// echo '<span class="label label-primary label-badge">' . $lang->branch->default . '</span>';
//}
//elseif($branch->status == 'active')
//{
// $setDefaultLink = helper::createLink('branch', 'setDefault', "productID=$productID&branchID=$branch->id", '', true);
// $setDefaultHtml = html::a($setDefaultLink, "<span><i class='icon icon-hand-right'></i> {$lang->branch->setDefault}</span>", 'hiddenwin', "class='btn btn-icon-left btn-sm setDefault hidden'");
echo common::hasPriv('branch', 'setDefault') ? $setDefaultHtml : '';
}
// echo common::hasPriv('branch', 'setDefault') ? $setDefaultHtml : '';
//}
?>
</td>
<td><?php echo zget($lang->branch->statusList, $branch->status);?></td>
+25 -7
View File
@@ -406,7 +406,8 @@ class bug extends control
if(isset($output['executionID']) and isonlybody())
{
$executionID = $this->post->execution ? $this->post->execution : $output['executionID'];
if($executionID == $output['executionID'] and $this->app->tab == 'execution')
$execution = $this->loadModel('execution')->getByID($executionID);
if($executionID == $output['executionID'] and $this->app->tab == 'execution' and $execution->type == 'kanban')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
@@ -414,7 +415,7 @@ class bug extends control
}
else
{
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'locate' => 'parent'));
}
}
@@ -541,7 +542,7 @@ class bug extends control
else
{
$builds = $this->loadModel('build')->getBuildPairs($productID, $branch, 'noempty,noterminate,nodone,withbranch');
$stories = $this->story->getProductStoryPairs($productID, $branch);
$stories = $this->story->getProductStoryPairs($productID, $branch, 0, 'all','id_desc', 0, 'full', 'story', false);
}
$moduleOwner = $this->bug->getModuleOwner($moduleID, $productID);
@@ -895,10 +896,12 @@ class bug extends control
* Edit a bug.
*
* @param int $bugID
* @param bool $comment
* @param string $kanbanGroup
* @access public
* @return void
*/
public function edit($bugID, $comment = false)
public function edit($bugID, $comment = false, $kanbanGroup = '')
{
if(!empty($_POST))
{
@@ -945,7 +948,21 @@ class bug extends control
}
}
}
if(isonlybody()) return print(js::reload('parent.parent'));
if(isonlybody())
{
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution' and $kanbanGroup == 'default')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData)"));
}
else
{
return print(js::closeModal('parent.parent'));
}
}
return print(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
}
@@ -1222,10 +1239,11 @@ class bug extends control
* Update assign of bug.
*
* @param int $bugID
* @parm string $kanbanGroup
* @access public
* @return void
*/
public function assignTo($bugID)
public function assignTo($bugID, $kanbanGroup = '')
{
$bug = $this->bug->getById($bugID);
$this->bug->checkBugExecutionPriv($bug);
@@ -1247,7 +1265,7 @@ class bug extends control
{
$bug = $this->bug->getById($bugID);
$execution = $this->loadModel('execution')->getByID($bug->execution);
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution')
if(isset($execution->type) and $execution->type == 'kanban' and $this->app->tab == 'execution' and $kanbanGroup == 'default')
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($bug->execution, $this->session->execLaneType ? $this->session->execLaneType : 'all');
$kanbanData = json_encode($kanbanData);
+1
View File
@@ -3,3 +3,4 @@
.table-data tr > td {word-break: break-all; word-wrap: break-word;}
.side-col .cell {padding: 0px;}
.tab-pane table {border: 1px solid #ddd; border-top: none;}
.btn-edit-comment {z-index: 100;}
+8 -1
View File
@@ -2665,7 +2665,14 @@ class bugModel extends model
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where($bugQuery)
->beginIF(!$this->app->user->admin)->andWhere('execution')->in('0,' . $this->app->user->view->sprints)->fi()
->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->beginIF($projectID)
->andWhere('project', true)->eq($projectID)
->orWhere('project')->eq(0)
->andWhere('openedBuild')->eq('trunk')
->markRight(1)
->fi()
->andWhere('deleted')->eq(0)
->orderBy($orderBy)->page($pager)->fetchAll();
return $bugs;
+1 -1
View File
@@ -41,7 +41,7 @@
if(count($moduleOptionMenu) == 1)
{
echo "<span class='input-group-btn'>";
echo html::a($this->createLink('tree', 'browse', "rootID=$libID&view=caselib&currentModuleID=0", 'html', true), "<i class='icon icon-cog'></i>", '', "data-toggle='tooltip' class='btn iframe' title='{$lang->tree->manage}'");
echo html::a($this->createLink('tree', 'browse', "rootID=$libID&view=caselib&currentModuleID=0", 'html', true), "<i class='icon icon-cog'></i>", '', "data-toggle='tooltip' class='btn iframe' data-width='95%' title='{$lang->tree->manage}'");
echo '</span>';
echo "<span class='input-group-btn'>";
echo html::a("javascript:void(0)", "<i class='icon icon-refresh'></i>", '', "class='btn refresh' title='{$lang->refresh}' onclick='loadLibModules($libID)'");
+1 -1
View File
@@ -296,7 +296,7 @@ $lang->kanban->dividerMenu = '';
/* Execution menu. */
$lang->execution->homeMenu = new stdclass();
$lang->execution->homeMenu->all = array('link' => "{$lang->execution->all}|execution|all|", 'alias' => 'batchedit');
$lang->execution->homeMenu->all = array('link' => "{$lang->execution->all}|execution|all|", 'alias' => 'create,batchedit');
if($config->systemMode == 'new') $lang->execution->homeMenu->executionkanban = array('link' => "{$lang->execution->executionKanban}|execution|executionkanban|");
$lang->execution->menu = new stdclass();
+1
View File
@@ -30,6 +30,7 @@ $lang->zentaoPMS = '禅道';
$lang->pmsName = '开源版';
$lang->proName = '专业版';
$lang->bizName = '企业版';
$lang->maxName = '旗舰版';
$lang->liteName = '迅捷版';
$lang->logoImg = 'zt-logo.png';
$lang->welcome = "%s项目管理系统";
+5 -5
View File
@@ -413,7 +413,7 @@ class commonModel extends model
{
if(!commonModel::isTutorialMode())
{
echo '<li>' . html::a(helper::createLink('tutorial', 'start'), "<i class='icon icon-guide'></i> " . $lang->tutorialAB, '', "class='iframe' data-class-name='modal-inverse' data-width='800' data-headerless='true' data-backdrop='true' data-keyboard='true'") . '</li>';
echo '<li class="user-tutorial">' . html::a(helper::createLink('tutorial', 'start'), "<i class='icon icon-guide'></i> " . $lang->tutorialAB, '', "class='iframe' data-class-name='modal-inverse' data-width='800' data-headerless='true' data-backdrop='true' data-keyboard='true'") . '</li>';
}
echo '<li>' . html::a(helper::createLink('my', 'preference', '', '', true), "<i class='icon icon-controls'></i> " . $lang->preference, '', "class='iframe' data-width='700'") . '</li>';
@@ -2403,13 +2403,13 @@ EOD;
/* Limited execution. */
$limitedExecution = false;
if(!empty($module) && $module == 'task' && !empty($object->execution) or
!empty($module) && $module == 'execution' && !empty($object->id)
if(!empty($module) && in_array($module, array('task', 'story')) && !empty($object->execution) or
!empty($module) && $module == 'execution' && !empty($object->id)
)
{
$objectID = '';
if($module == 'execution' and !empty($object->id)) $objectID = $object->id;
if($module == 'task' and !empty($object->execution))$objectID = $object->execution;
if($module == 'execution' and !empty($object->id)) $objectID = $object->id;
if(in_array($module, array('task', 'story')) and !empty($object->execution)) $objectID = $object->execution;
$limitedExecutions = !empty($_SESSION['limitedExecutions']) ? $_SESSION['limitedExecutions'] : '';
if($objectID and strpos(",{$limitedExecutions},", ",$objectID,") !== false) $limitedExecution = true;
+5 -2
View File
@@ -30,7 +30,10 @@ $(function()
}
$dropmenu.append("<li><a href='javascript:saveDatatableConfig(\"mode\", \"<?php echo $mode == 'table' ? 'datatable' : 'table';?>\", true);' id='switchToDatatable'><?php echo $mode == 'table' ? $lang->datatable->switchToDatatable : $lang->datatable->switchToTable;?></a></li>");
$dropdown.append($dropmenu).appendTo($btnToolbar);
$dropdown.append($dropmenu)
.appendTo($btnToolbar)
.on('shown.zui.dropdown', function(){$btnToolbar.closest('.table-header').css('z-index', 11);})
.on('hidden.zui.dropdown', function(){$btnToolbar.closest('.table-header').css('z-index', 5);});
}
};
$('#main .main-table').on('tableReload', addSettingButton);
@@ -95,7 +98,7 @@ $(function()
<form class='form-condensed' method='post' target='hiddenwin' action='<?php echo $this->createLink('datatable', 'ajaxSave')?>'>
<table class='table table-form'>
<tr>
<td class='w-150px'><?php echo $lang->datatable->showModule;?></td>
<td class='w-160px'><?php echo $lang->datatable->showModule;?></td>
<td><?php echo html::radio('showModule', $lang->datatable->showModuleList, isset($config->datatable->$datatableId->showModule) ? $config->datatable->$datatableId->showModule : '');?></td>
</tr>
<?php if($app->moduleName == 'execution' and $app->methodName == 'task' and $this->config->vision != 'lite'):?>
+4 -1
View File
@@ -7,7 +7,7 @@ $.initSidebar();
<iframe frameborder='0' name='hiddenwin' id='hiddenwin' scrolling='no' class='debugwin hidden'></iframe>
<?php if($onlybody != 'yes' and $app->viewType != 'xhtml'):?>
</main><?php /* end '#wrap' in 'header.html.php'. */ ?>
<div id="noticeBox"><?php echo $this->loadModel('score')->getNotice(); ?></div>
<div id="noticeBox"><?php if($config->vision != 'lite') echo $this->loadModel('score')->getNotice(); ?></div>
<script>
<?php $this->app->loadConfig('message');?>
<?php if($config->message->browser->turnon):?>
@@ -73,6 +73,9 @@ if($this->config->vision == 'lite')
$extHookFiles = glob($extHookRule);
if($extHookFiles) foreach($extHookFiles as $extHookFile) include $extHookFile;
}
$extHookRule = $extensionRoot . 'custom/common/ext/view/footer.*.hook.php';
$extHookFiles = glob($extHookRule);
if($extHookFiles) foreach($extHookFiles as $extHookFile) include $extHookFile;
?>
</body>
</html>
+4
View File
@@ -48,6 +48,10 @@ include 'chosen.html.php';
<?php endif;?>
<script>
adjustMenuWidth();
if(window.navigator.userAgent.indexOf('xuanxuan') > 0)
{
$('li.user-tutorial').addClass('hide');
}
</script>
<main id='main' <?php if(!empty($config->sso->redirect)) echo "class='ranzhiFixedTfootAction'";?> >
<div class='container'>
+2
View File
@@ -77,6 +77,8 @@ if($this->config->vision == 'lite')
$extHookFiles = glob($extHookRule);
if($extHookFiles) foreach($extHookFiles as $extHookFile) include $extHookFile;
}
$xuanExtFile = $extensionRoot . 'xuan/common/ext/view/header.xuanxuan.html.hook.php';
if(file_exists($xuanExtFile)) include $xuanExtFile;
?>
</head>
<?php $singleClass = $this->app->getViewType() == 'xhtml' ? 'allow-self-open' : '';?>
+2 -2
View File
@@ -204,7 +204,8 @@ class company extends control
$pager = new pager($recTotal, $recPerPage = 50, $pageID = 1);
/* Append id for secend sort. */
$orderBy = $direction == 'next' ? 'date_desc' : 'date_asc';
if($direction == 'next') $orderBy = 'date_desc';
if($direction == 'pre') $orderBy = 'date_asc';
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$date = empty($date) ? '' : date('Y-m-d', $date);
@@ -288,7 +289,6 @@ class company extends control
$this->view->pager = $pager;
$this->view->userID = $userID;
$this->view->param = $param;
$this->view->browseType = $browseType;
$this->view->dateGroups = $this->action->buildDateGroup($actions, $direction, $browseType, $orderBy);
$this->view->direction = $direction;
$this->display();
+2 -2
View File
@@ -1,12 +1,12 @@
$('#account, #product, #project, #execution, #orderBy').change(function()
{
var userID = $('#account').val();
var productID = $('#product').val();
var productID = $('#product').length ? $('#product').val() : 0;
var projectID = systemMode == 'new' ? $('#project').val() : 0;
var executionID = $('#execution').val();
var orderBy = $('#orderBy').val();
browseType = browseType == 'bysearch' ? 'all' : browseType;
link = createLink('company', 'dynamic', 'browseType=' + browseType + '&param=&recTotal=0&date=&direction=next&userID=' + userID + '&productID=' + productID + '&projectID=' + projectID + '&executionID=' + executionID + '&orderBy=' + orderBy);
link = createLink('company', 'dynamic', 'browseType=' + browseType + '&param=&recTotal=0&date=&direction=no&userID=' + userID + '&productID=' + productID + '&projectID=' + projectID + '&executionID=' + executionID + '&orderBy=' + orderBy);
location.href = link;
})
+1 -1
View File
@@ -46,7 +46,7 @@ $config->custom->fieldList['story']['review'] = 'reviewedDate,comment';
$config->custom->fieldList['productplan'] = 'begin,end,desc';
$config->custom->fieldList['release']['create'] = 'desc';
$config->custom->fieldList['release']['edit'] = 'desc';
$config->custom->fieldList['execution']['create'] = 'days,desc';
$config->custom->fieldList['execution']['create'] = 'days,desc,PO,PM,QD,RD';
$config->custom->fieldList['execution']['edit'] = 'days,desc,PO,PM,QD,RD';
$config->custom->fieldList['task']['create'] = 'story,pri,estimate,desc,estStarted,deadline';
$config->custom->fieldList['task']['edit'] = 'pri,estimate,estStarted,deadline';
+1 -1
View File
@@ -20,7 +20,7 @@ class custom extends control
public function index()
{
if($this->config->vision == 'lite') return print(js::locate(inlink('execution')));
if(($this->config->systemMode == 'new') and common::hasPriv('custom', 'set'))
{
return print(js::locate(inlink('set', "module=project&field=" . key($this->lang->custom->project->fields))));
+2 -1
View File
@@ -39,8 +39,9 @@
<th class='thWidth'>
<?php
$fields = $this->custom->getFormFields($moduleName, $method);
if(empty($fields)) continue;
if($moduleName == 'caselib' and $method == 'createcase') continue;
$actionKey = $method . 'Action';
if(isset($lang->$moduleName->$actionKey))
{
+1 -1
View File
@@ -112,7 +112,7 @@ class deptModel extends model
krsort($deptMenu);
$topMenu = array_pop($deptMenu);
$topMenu = explode("\n", trim($topMenu));
$topMenu = explode("\n", trim((string)$topMenu));
$lastMenu[] = '/';
foreach($topMenu as $menu)
{
+5 -3
View File
@@ -276,6 +276,7 @@ class design extends control
$this->view->design = $design;
$this->view->project = $this->loadModel('project')->getByID($design->project);
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($design->product);
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->display();
}
@@ -307,8 +308,6 @@ class design extends control
$repos = $this->loadModel('repo')->getRepoPairs('project', $design->project);
$repoID = $repoID ? $repoID : key($repos);
if(empty($repoID)) return print(js::locate(helper::createLink('repo', 'create', "objectID=$design->project")));
$repo = $this->loadModel('repo')->getRepoByID($repoID);
$revisions = $this->repo->getCommits($repo, '', 'HEAD', '', '', $begin, $end);
@@ -398,12 +397,15 @@ class design extends control
$this->app->loadClass('pager', $static = true);
$pager = pager::init(0, $recPerPage, $pageID);
$design = $this->design->getCommit($designID, $pager);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->submission;
$this->view->position[] = $this->lang->design->submission;
$this->view->design = $this->design->getCommit($designID, $pager);
$this->view->design = $design;
$this->view->pager = $pager;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->repos = $this->loadModel('repo')->getRepoPairs('project', $design->project);
$this->display();
}
+2
View File
@@ -0,0 +1,2 @@
#mainContent .pull-right{margin-bottom: 10px}
.table{border: 1px solid #ddd;}
+20
View File
@@ -0,0 +1,20 @@
$(function()
{
$('#linkCommit').click(function()
{
if(repos.length == 0)
{
var onlybody = config.onlybody;
config.onlybody = 'no';
var link = createLink('repo', 'create', 'objectID=' + projectID);
config.onlybody = onlybody;
window.parent.$.apps.open(link, 'devops');
parent.$('#triggerModal').modal('hide');
return false;
}
});
});
+2 -2
View File
@@ -51,9 +51,9 @@
<td class='c-actions text-center'>
<?php
$vars = "design={$design->id}";
common::printIcon('design', 'edit', $vars, $design, 'list', 'alter', '', '', '', '', '', $design->project);
common::printIcon('design', 'edit', $vars, $design, 'list', 'alter');
common::printIcon('design', 'viewCommit', $vars, $design, 'list', 'list-alt', '', 'iframe showinonlybody', true);
common::printIcon('design', 'delete', $vars, $design, 'list', 'trash', 'hiddenwin', '', '', '', '', $design->project);
common::printIcon('design', 'delete', $vars, $design, 'list', 'trash', 'hiddenwin');
?>
</td>
</tr>
+3 -5
View File
@@ -11,10 +11,8 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<style>
#mainContent .pull-right{margin-bottom: 10px}
.table{border: 1px solid #ddd;}
</style>
<?php js::set('repos', $repos);?>
<?php js::set('projectID', $design->project);?>
<div id="mainContent">
<div class='main-header'>
<h2>
@@ -24,7 +22,7 @@
</h2>
</div>
<div class='btn-toolbar pull-right'>
<?php common::printLink('design', 'linkCommit', "designID=$design->id", "<i class='icon icon-plus'></i>" . $lang->design->linkCommit, '_blank', "class='btn btn-primary'");?>
<?php common::printLink('design', 'linkCommit', "designID=$design->id", "<i class='icon icon-plus'></i>" . $lang->design->linkCommit, '', "class='btn btn-primary' id='linkCommit'");?>
</div>
<?php if(empty($design->commit)):?>
<div class="table-empty-tip">
+12 -10
View File
@@ -1,5 +1,4 @@
<?php
/**
* The control file of doc module of ZenTaoPMS.
*
@@ -155,7 +154,7 @@ class doc extends control
$executions = $this->execution->getList();
/* Splice project name. */
foreach($executions as $executionID => $execution) $executions[$executionID] = $projects[$execution->parent] . '/' . $execution->name;
foreach($executions as $executionID => $execution) $executions[$executionID] = $projects[$execution->project] . '/' . $execution->name;
/* Get the project that has permission to view. */
foreach($projects as $projectID => $project) if(!$this->app->user->admin and strpos(',' . $this->app->user->view->projects . ',', ',' . $projectID . ',') === false) unset($projects[$projectID]);
@@ -538,14 +537,15 @@ class doc extends control
$this->view->position[] = html::a($this->createLink('doc', 'browse', "libID=$doc->lib"), $lib->name);
$this->view->position[] = $this->lang->doc->view;
$this->view->doc = $doc;
$this->view->lib = $lib;
$this->view->type = $type;
$this->view->version = $version ? $version : $doc->version;
$this->view->actions = $this->action->getList('doc', $docID);
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID);
$this->view->keTableCSS = $this->doc->extractKETableCSS($doc->content);
$this->view->doc = $doc;
$this->view->lib = $lib;
$this->view->type = $type;
$this->view->version = $version ? $version : $doc->version;
$this->view->actions = $this->action->getList('doc', $docID);
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID);
$this->view->keTableCSS = $this->doc->extractKETableCSS($doc->content);
$this->view->autoloadPage = $this->doc->checkAutoloadPage($doc);
$this->display();
}
@@ -1067,6 +1067,8 @@ class doc extends control
$this->view->actions = $docID ? $this->action->getList('doc', $docID) : array();
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->preAndNext = $this->doc->getPreAndNextDoc($docID, $libID);
$this->view->autoloadPage = $this->doc->checkAutoloadPage($doc);
$this->display();
}
+2
View File
@@ -99,3 +99,5 @@ ol, ul {margin-bottom: 0}
.tree li.active > .tree-group a {font-weight: 700; color: #0c64eb;}
.tree li>.list-toggle {left: -4px; top: 0;}
.fullscreen-close {top: 8px !important;}
+1 -1
View File
@@ -7,4 +7,4 @@ table {width: 90% !important;}
#product_chosen {width: 50% !important;}
#execution_chosen {width: 50% !important;}
#whiteListBox .input-group:last-child {margin-top: 10px;}
#groups_chosen.chosen-container .chosen-results, #users_chosen.chosen-container .chosen-results {max-height: 160px;}
+2
View File
@@ -1,3 +1,5 @@
#whiteListBox .input-group:last-child {margin-top: 10px;}
#mainContent .main-header h2 {width: 90%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.fullscreen-save, .markdown-fullscreen-save {position: fixed; top: 10px; right: 30px; z-index: 999999;}
.modal-header .fullscreen-save, .markdown-fullscreen-save {top: 5px; right: 60px;}
+1
View File
@@ -4,3 +4,4 @@ form {margin-right: 30px;}
#whiteListBox .input-group:last-child {margin-top: 10px;}
.center-block {margin-top: 20px;}
#groups_chosen.chosen-container .chosen-results, #users_chosen.chosen-container .chosen-results {max-height: 160px;}
+28
View File
@@ -82,6 +82,34 @@ $(function()
}
}, 200);
}
else
{
setTimeout(function()
{
if($('a[title="Fullscreen"]').hasClass('active'))
{
$('.main-header').hide();
$('#submit').addClass('markdown-fullscreen-save');
$('#submit').removeClass('btn-wide');
$('#mainContent .fullscreen').css('padding-top', '8px');
$('#mainContent .fullscreen').css('height', '40px');
$('.CodeMirror-fullscreen').css('top', '40px');
$('.editor-preview-side').css('top', '40px');
$('#submit').data('placement', 'left');
parent.$('.modal-header > .close').addClass('fullscreen-close');
}
else
{
$('.main-header').show();
$('#submit').removeClass('markdown-fullscreen-save');
$('#mainContent .editor-toolbar').css('padding', '1px');
$('#mainContent .editor-toolbar').css('height', '30px');
$('.CodeMirror').css('top', '0px');
$('.editor-preview-side').css('top', '0px');
parent.$('.modal-header > .close').removeClass('fullscreen-close');
}
}, 200);
}
});
})
+22 -1
View File
@@ -1530,9 +1530,9 @@ class docModel extends model
{
$issueIdList = $this->dao->select('id')->from(TABLE_ISSUE)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('project')->in($this->app->user->view->projects)->get();
$meetingIdList = $this->dao->select('id')->from(TABLE_MEETING)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('project')->in($this->app->user->view->projects)->get();
$designIdList = $this->dao->select('id')->from(TABLE_DESIGN)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('project')->in($this->app->user->view->projects)->get();
}
$designIdList = $this->dao->select('id')->from(TABLE_DESIGN)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('project')->in($this->app->user->view->projects)->get();
$executionIdList = $this->loadModel('execution')->getIdList($objectID);
$taskPairs = $this->dao->select('id')->from(TABLE_TASK)->where('execution')->in($executionIdList)->andWhere('deleted')->eq('0')->andWhere('execution')->in($this->app->user->view->sprints)->fetchPairs('id');
if(!empty($taskPairs)) $taskIdList = implode(',', $taskPairs);
@@ -2651,4 +2651,25 @@ EOT;
return array($libs, $libID, $object, $objectID);
}
/**
* Whether the url of link type documents needs to be autoloaded.
*
* @param object $doc
* @access public
* @return bool
*/
public function checkAutoloadPage($doc)
{
$autoloadPage = true;
if(!empty($doc) and $doc->type == 'url')
{
$parsedUrl = parse_url($doc->content);
$urlPort = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
$urlDomain = $parsedUrl['host'] . $urlPort;
if($urlDomain == $_SERVER['HTTP_HOST']) $autoloadPage = false;
}
return $autoloadPage;
}
}
+1 -1
View File
@@ -74,7 +74,7 @@ $sessionString .= session_name() . '=' . session_id();
</p>
<?php endif;?>
<?php
if($doc->type == 'url')
if($doc->type == 'url' and $autoloadPage)
{
$url = $doc->content;
if(!preg_match('/^https?:\/\//', $doc->content)) $url = 'http://' . $url;
+1 -1
View File
@@ -89,7 +89,7 @@ js::set('docID', $doc->id);
<div class="detail no-padding">
<div class="detail-content article-content no-margin no-padding">
<?php
if($doc->type == 'url')
if($doc->type == 'url' and $autoloadPage)
{
$url = $doc->content;
if(!preg_match('/^https?:\/\//', $doc->content)) $url = 'http://' . $url;
+7 -23
View File
@@ -1263,24 +1263,7 @@ class execution extends control
*/
public function create($projectID = '', $executionID = 0, $copyExecutionID = '', $planID = 0, $confirm = 'no', $productID = 0, $extra = '')
{
/* Set menu. */
if($this->app->tab == 'project')
{
if(!empty($copyExecutionID)) $projectID = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($copyExecutionID)->fetch('project');
$projectID = $this->project->saveState($projectID, $this->project->getPairsByProgram());
$this->project->setMenu($projectID);
}
elseif($this->app->tab == 'execution')
{
$selectedExecutionID = $executionID;
if($this->config->systemMode == 'new') $selectedExecutionID = key($this->executions);
$this->execution->setMenu($selectedExecutionID);
}
elseif($this->app->tab == 'doc')
{
unset($this->lang->doc->menu->execution['subMenu']);
}
if($this->app->tab == 'doc') unset($this->lang->doc->menu->execution['subMenu']);
$project = $this->project->getByID($projectID);
if(!empty($project) and $project->model == 'kanban')
@@ -1988,7 +1971,7 @@ class execution extends control
if($execution->type == 'kanban')
{
if(defined('RUN_MODE') && RUN_MODE == 'api') return print($this->fetch('execution', 'kanban', "executionID=$executionID"));
return $this->locate(inlink('kanban', "executionID=$executionID"));
return print(js::locate(inlink('kanban', "executionID=$executionID")));
}
$this->app->loadLang('program');
@@ -2058,7 +2041,7 @@ class execution extends control
$this->lang->execution->menu = new stdclass();
$execution = $this->commonAction($executionID);
if($execution->type != 'kanban') return $this->locate(inlink('view', "executionID=$executionID"));
if($execution->type != 'kanban') return print(js::locate(inlink('view', "executionID=$executionID")));
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy);
$executionActions = array();
@@ -2840,7 +2823,7 @@ class execution extends control
/* Build the search form. */
$actionURL = $this->createLink($this->app->rawModule, 'linkStory', "objectID=$objectID&browseType=bySearch&queryID=myQueryID");
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'noclosed');
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
$this->execution->buildStorySearchForm($products, $branchGroups, $modules, $queryID, $actionURL, 'linkStory', $objectID);
if($browseType == 'bySearch')
@@ -3278,7 +3261,7 @@ class execution extends control
* @access public
* @return void
*/
public function all($status = 'all', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $recTotal = 0, $recPerPage = 10, $pageID = 1)
public function all($status = 'all', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $recTotal = 0, $recPerPage = 100, $pageID = 1)
{
$this->app->loadLang('my');
$this->app->loadLang('product');
@@ -3296,7 +3279,8 @@ class execution extends control
$this->view->project = $project;
$this->project->setMenu($projectID);
if(!empty($project->model) and $project->model == 'kanban' and !(defined('RUN_MODE') and RUN_MODE == 'api')) return $this->locate($this->createLink('project', 'index', "projectID=$projectID"));
if(!$projectID) return print(js::locate($this->createLink('project', 'browse')));
if(!empty($project->model) and $project->model == 'kanban' and !(defined('RUN_MODE') and RUN_MODE == 'api')) return print(js::locate($this->createLink('project', 'index', "projectID=$projectID")));
}
if($this->app->viewType == 'mhtml')
+1
View File
@@ -6,3 +6,4 @@ th.c-deadline {text-align: center;}
.c-estimate {text-align: right;}
.c-consumed {text-align: right;}
.c-left {text-align: right;}
.table-footer {z-index: 1;}
+31 -23
View File
@@ -233,13 +233,15 @@ $('.c-group').change(function()
*/
function createLaneMenu(options)
{
var lane = options.$trigger.closest('.kanban-lane').data('lane');
var lane = options.$trigger.closest('.kanban-lane').data('lane');
var laneCount = options.$trigger.closest('.kanban-board').children('.kanban-lane').length;
var privs = lane.actions;
if(!privs.length) return [];
var items = [];
if(privs.includes('setLane')) items.push({label: kanbanLang.setLane, icon: 'edit', url: createLink('kanban', 'setLane', 'laneID=' + lane.id + '&executionID=0&from=kanban'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '635px'}});
if(privs.includes('deleteLane')) items.push({label: kanbanLang.deleteLane, icon: 'trash', url: createLink('kanban', 'deleteLane', 'lane=' + lane.id), attrs: {'target': 'hiddenwin'}});
if(privs.includes('deleteLane') && laneCount > 1) items.push({label: kanbanLang.deleteLane, icon: 'trash', url: createLink('kanban', 'deleteLane', 'lane=' + lane.id), attrs: {'target': 'hiddenwin'}});
var bounds = options.$trigger[0].getBoundingClientRect();
items.$options = {x: bounds.right, y: bounds.top};
@@ -361,6 +363,8 @@ function findDropColumns($element, $root)
var laneType = $element.closest('.kanban-lane').data().lane.type;
var kanbanRules = window.kanbanDropRules ? window.kanbanDropRules[laneType] : null;
hideKanbanAction();
if(!kanbanRules) return $root.find('.kanban-lane-col:not([data-type="' + col.type + '"])');
var colRules = kanbanRules[col.type];
@@ -393,17 +397,17 @@ function renderUserAvatar(user, objectType, objectID, size)
if(objectType == 'task')
{
if(!priv.canAssignTask && !user) return $noPrivAndNoAssigned;
var link = createLink('task', 'assignto', 'executionID=' + executionID + '&id=' + objectID, '', true);
var link = createLink('task', 'assignto', 'executionID=' + executionID + '&id=' + objectID + '&kanbanGroup=' + groupBy, '', true);
}
if(objectType == 'story')
{
if(!priv.canAssignStory && !user) return $noPrivAndNoAssigned;
var link = createLink('story', 'assignto', 'id=' + objectID, '', true);
var link = createLink('story', 'assignto', 'id=' + objectID + '&kanbanGroup=' + groupBy, '', true);
}
if(objectType == 'bug')
{
if(!priv.canAssignBug && !user) return $noPrivAndNoAssigned;
var link = createLink('bug', 'assignto', 'id=' + objectID, '', true);
var link = createLink('bug', 'assignto', 'id=' + objectID + '&kanbanGroup=' + groupBy, '', true);
}
if(!user) return $('<a class="avatar has-text ' + avatarSizeClass + ' avatar-circle iframe" title="' + noAssigned + '" style="background: #ccc" href="' + link + '" data-toggle="modal" data-width="80%"><i class="icon icon-person"></i></a>');
@@ -991,23 +995,27 @@ function changeCardColType(cardID, fromColID, toColID, fromLaneID, toLaneID, car
*/
function deleteCard(objectType, objectID, regionID)
{
var objectLang = objectType + 'Lang';
var result = confirm(window[objectLang].confirmDelete) ? true : false;
if(!result) return false;
if(!objectID) return false;
var url = createLink('kanban', 'deleteObjectCard', 'objectType=' + objectType + '&objectID=' + objectID + '&regionID=' + regionID);
return $.ajax(
$.zui.ContextMenu.hide();
setTimeout(function()
{
method: 'post',
dataType: 'json',
url: url,
success: function(data)
var objectLang = objectType + 'Lang';
var result = confirm(window[objectLang].confirmDelete) ? true : false;
if(!result) return false;
if(!objectID) return false;
var url = createLink('kanban', 'deleteObjectCard', 'objectType=' + objectType + '&objectID=' + objectID + '&regionID=' + regionID);
return $.ajax(
{
updateRegion(regionID, data[regionID]);
}
});
method: 'post',
dataType: 'json',
url: url,
success: function(data)
{
updateRegion(regionID, data[regionID]);
}
});
}, 200)
}
/**
@@ -1106,7 +1114,7 @@ function createStoryMenu(options)
var items = [];
var showAction = story.$col.type == 'backlog' || story.$col.type == 'ready' || story.$col.type == 'developing' || story.$col.type == 'developed' || story.$col.type == 'testing' || story.$col.type == 'tested' || story.$col.type == 'verified' || story.$col.type == 'released';
if(priv.canEditStory) items.push({label: storyLang.edit, icon: 'edit', url: createLink('story', 'edit', 'storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canEditStory) items.push({label: storyLang.edit, icon: 'edit', url: createLink('story', 'edit', 'storyID=' + story.id + '&kanbanGroup=' + groupBy, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canChangeStory && showAction) items.push({label: storyLang.change, icon: 'change', url: createLink('story', 'change', 'storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canCreateTask && showAction) items.push({label: executionLang.wbs, icon: 'plus', url: createLink('task', 'create', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canBatchCreateTask && showAction) items.push({label: executionLang.batchWBS, icon: 'pluses', url: createLink('task', 'batchCreate', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
@@ -1125,7 +1133,7 @@ function createTaskMenu(options)
var $card = options.$trigger.closest('.kanban-item');
var task = $card.data('item');
var items = [];
if(priv.canEditTask) items.push({label: taskLang.edit, icon: 'edit', url: createLink('task', 'edit', 'taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canEditTask) items.push({label: taskLang.edit, icon: 'edit', url: createLink('task', 'edit', 'taskID=' + task.id + '&comment=&kanbanGroup=' + groupBy, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canRestartTask && task.$col.type == 'pause') items.push({label: taskLang.restart, icon: 'play', url: createLink('task', 'restart', 'taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canPauseTask && task.$col.type == 'developing') items.push({label: taskLang.pause, icon: 'pause', url: createLink('task', 'pause', 'taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canRecordEstimateTask) items.push({label: executionLang.effort, icon: 'time', url: createLink('task', 'recordEstimate', 'taskID=' + task.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
@@ -1145,7 +1153,7 @@ function createBugMenu(options)
var $card = options.$trigger.closest('.kanban-item');
var bug = $card.data('item');
var items = [];
if(priv.canEditBug) items.push({label: bugLang.edit, icon: 'edit', url: createLink('bug', 'edit', 'bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canEditBug) items.push({label: bugLang.edit, icon: 'edit', url: createLink('bug', 'edit', 'bugID=' + bug.id + '&comment=&kanbanGroup=' + groupBy, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canResolveBug && (bug.$col.type == 'unconfirmed' || bug.$col.type == 'confirmed' || bug.$col.type == 'fixing')) items.push({label: bugLang.resolve, icon: 'checked', url: createLink('bug', 'resolve', 'bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canConfirmBug && (bug.$col.type == 'fixed' || bug.$col.type == 'testing' || bug.$col.type == 'tested')) items.push({label: bugLang.close, icon: 'off', url: createLink('bug', 'close', 'bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canConfirmBug && bug.$col.type == 'unconfirmed') items.push({label: bugLang.confirmBug, icon: 'ok', url: createLink('bug', 'confirmbug', 'bugID=' + bug.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
+1 -1
View File
@@ -38,6 +38,6 @@ function adjustTableFooter()
{
$('.table.with-footer-fixed').css('margin-bottom', '0');
$('.table-footer').removeClass('fixed-footer');
$('.table-footer').css({"left":"0", "bottom":"0", "width":"unset"});
$('.table-footer').css({'left': 0, 'bottom': 0, 'width': 'unset'});
}
}
+7
View File
@@ -515,6 +515,8 @@ function findDropColumns($element, $root)
var kanbanID = $root.data('id');
var kanbanRules = window.kanbanDropRules ? window.kanbanDropRules[kanbanID] : null;
$.zui.ContextMenu.hide();
if(!kanbanRules) return $root.find('.kanban-lane-col:not([data-type="' + col.type + '"])');
var colRules = kanbanRules[col.type];
@@ -1238,3 +1240,8 @@ function resetKanbanHeight()
$('.kanban-lane').css('height', height -2);
}
$(document).on('click', '.dropdown-menu', function()
{
$.zui.ContextMenu.hide();
});
+1
View File
@@ -222,6 +222,7 @@ $lang->execution->exportAction = "Export Execution";
$lang->execution->computeBurnAction = "Update Burndown";
$lang->execution->create = "Create {$lang->executionCommon}";
$lang->execution->createExec = "Create {$lang->execution->common}";
$lang->execution->createAction = "Create {$lang->execution->common}";
$lang->execution->copyExec = "Copy {$lang->execution->common}";
$lang->execution->copy = "Copy {$lang->executionCommon}";
$lang->execution->delete = "Delete {$lang->executionCommon}";
+1
View File
@@ -222,6 +222,7 @@ $lang->execution->exportAction = "导出{$lang->execution->common}";
$lang->execution->computeBurnAction = "计算燃尽图";
$lang->execution->create = "添加{$lang->executionCommon}";
$lang->execution->createExec = "添加{$lang->execution->common}";
$lang->execution->createAction = "添加{$lang->execution->common}";
$lang->execution->copyExec = "复制{$lang->execution->common}";
$lang->execution->copy = "复制{$lang->executionCommon}";
$lang->execution->delete = "删除{$lang->executionCommon}";
+27 -14
View File
@@ -246,17 +246,22 @@ class executionModel extends model
$executionID = (int)$this->cookie->lastExecution;
$executionID = in_array($executionID, array_keys($executions)) ? $executionID : key($executions);
}
if($executionID == 0 and $this->session->execution == '') $executionID = key($executions);
if($executionID == 0 and $this->session->execution) $executionID = $this->session->execution;
if($executionID == 0) $executionID = key($executions);
$this->session->set('execution', (int)$executionID, $this->app->tab);
if(!isset($executions[$executionID]))
{
$this->session->set('execution', key($executions), $this->app->tab);
$execution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->andWhere('type')->in('sprint,stage,kanban')->fetch();
if(empty($execution)) return js::error($this->lang->notFound);
if($executionID && strpos(",{$this->app->user->view->sprints},", ",{$executionID},") === false) $this->accessDenied();
if($executionID)
{
$execution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->andWhere('type')->in('sprint,stage,kanban')->fetch();
if(empty($execution)) return js::error($this->lang->notFound);
if(strpos(",{$this->app->user->view->sprints},", ",{$executionID},") === false) $this->accessDenied();
}
}
$this->setProjectSession($this->session->execution);
@@ -512,9 +517,9 @@ class executionModel extends model
->where('id')->eq($executionID)
->limit(1)
->exec();
if(dao::isError()) return false;
/* Get team and language item. */
$this->loadModel('user');
$team = $this->user->getTeamMemberPairs($executionID, 'execution');
@@ -681,12 +686,12 @@ class executionModel extends model
$projectID = isset($execution->project) ? $execution->project : $oldExecution->project;
$project = $this->project->getByID($projectID);
if($execution->begin < $project->begin)
if($project and $execution->begin < $project->begin)
{
dao::$errors['begin'] = sprintf($this->lang->execution->errorLetterProject, $project->begin);
return false;
}
if($execution->end > $project->end)
if($project and $execution->end > $project->end)
{
dao::$errors['end'] = sprintf($this->lang->execution->errorGreaterProject, $project->end);
return false;
@@ -962,6 +967,7 @@ class executionModel extends model
->andWhere('t2.type')->eq('stage')
->andWhere('t2.grade')->eq(1)
->andWhere('t2.deleted')->eq(0)
->andWhere('t2.parent')->eq($oldExecution->parent)
->fetch('total');
if($type == 'create') $percentTotal = $percent + $oldPercentTotal;
@@ -1133,10 +1139,11 @@ class executionModel extends model
* @param int $limit
* @param int $productID
* @param int $branch
* @param object $pager
* @access public
* @return array
*/
public function getList($projectID = 0, $type = 'all', $status = 'all', $limit = 0, $productID = 0, $branch = 0)
public function getList($projectID = 0, $type = 'all', $status = 'all', $limit = 0, $productID = 0, $branch = 0, $pager = null)
{
if($status == 'involved') return $this->getInvolvedExecutionList($projectID, $status, $limit, $productID, $branch);
@@ -1154,6 +1161,7 @@ class executionModel extends model
->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi()
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
->orderBy('order_desc')
->page($pager)
->beginIF($limit)->limit($limit)->fi()
->fetchAll('id');
}
@@ -1161,6 +1169,7 @@ class executionModel extends model
{
return $this->dao->select('*, IF(INSTR(" done,closed", status) < 2, 0, 1) AS isDone')->from(TABLE_EXECUTION)
->where('deleted')->eq(0)
->andWhere('vision')->eq($this->config->vision)
->beginIF($type == 'all')->andWhere('type')->in('sprint,stage,kanban')->fi()
->beginIF($type != 'all')->andWhere('type')->eq($type)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
@@ -1168,6 +1177,7 @@ class executionModel extends model
->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->orderBy('order_desc')
->page($pager)
->beginIF($limit)->limit($limit)->fi()
->fetchAll('id');
}
@@ -1260,6 +1270,7 @@ class executionModel extends model
$executions = $this->dao->select('*')->from(TABLE_EXECUTION)
->where('type')->in('stage,sprint,kanban')
->andWhere('deleted')->eq('0')
->andWhere('vision')->eq($this->config->vision)
->beginIF($projectID)->andWhere('project')->eq((int)$projectID)->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->beginIF($status == 'undone')->andWhere('status')->notIN('done,closed')->fi()
@@ -1670,9 +1681,9 @@ class executionModel extends model
$execution->days = $execution->days ? $execution->days : '';
$execution->totalHours = $this->dao->select('sum(days * hours) AS totalHours')->from(TABLE_TEAM)->where('root')->eq($execution->id)->andWhere('type')->eq('execution')->fetch('totalHours');
$execution->totalEstimate = round($total->totalEstimate, 1);
$execution->totalConsumed = round($total->totalConsumed, 1);
$execution->totalLeft = round($total->totalLeft - $closedTotalLeft, 1);
$execution->totalEstimate = round((float)$total->totalEstimate, 1);
$execution->totalConsumed = round((float)$total->totalConsumed, 1);
$execution->totalLeft = round((float)($total->totalLeft - $closedTotalLeft), 1);
$execution = $this->loadModel('file')->replaceImgURL($execution, 'desc');
if($setImgSize) $execution->desc = $this->file->setImgSize($execution->desc);
@@ -1825,7 +1836,7 @@ class executionModel extends model
foreach($plans as $plan) $planPairs += $plan;
}
$this->config->product->search['params']['plan']['values'] = $planPairs;
$this->config->product->search['params']['module']['values'] = $modules;
$this->config->product->search['params']['module']['values'] = array('' => '') + $modules;
if($productType == 'normal')
{
unset($this->config->product->search['fields']['branch']);
@@ -2353,6 +2364,7 @@ class executionModel extends model
$this->linkCases($executionID, (int)$products[$storyID], $storyID);
$action = $executionID == $this->session->project ? 'linked2project' : 'linked2execution';
if($action == 'linked2execution' and $execution->type == 'kanban') $action = 'linked2kanban';
$this->action->create('story', $storyID, $action, '', $executionID);
}
@@ -2995,6 +3007,7 @@ class executionModel extends model
}
$parents = $this->dao->select('*')->from(TABLE_TASK)->where('id')->in($parents)->fetchAll('id');
if($this->config->vision == 'lite') $tasks = $this->loadModel('task')->appendLane($tasks);
foreach($tasks as $task)
{
if($task->parent > 0)
+1 -1
View File
@@ -11,7 +11,7 @@
*/
?>
<?php if(isset($tips)):?>
<?php $defaultURL = $this->createLink('execution', 'all');?>
<?php $defaultURL = $this->createLink('execution', 'task', "execution=$executionID");?>
<?php include '../../common/view/header.html.php';?>
<body>
<div class='modal-dialog mw-500px' id='tipsModal'>
+3 -3
View File
@@ -58,9 +58,9 @@ $canDeleteRegion = commonModel::hasPriv('kanban', 'deleteRegion');
$canCreateLane = commonModel::hasPriv('kanban', 'createLane');
$canCreateTask = common::hasPriv('task', 'create');
$canBatchCreateTask = common::hasPriv('task', 'batchCreate');
$canCreateBug = common::hasPriv('bug', 'create');
$canBatchCreateBug = common::hasPriv('bug', 'batchCreate');
$canImportBug = common::hasPriv('execution', 'importBug');
$canCreateBug = ($productID and common::hasPriv('bug', 'create'));
$canBatchCreateBug = ($productID and common::hasPriv('bug', 'batchCreate'));
$canImportBug = ($productID and common::hasPriv('execution', 'importBug'));
$canCreateStory = ($productID and common::hasPriv('story', 'create'));
$canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate'));
$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory'));
+8 -4
View File
@@ -179,12 +179,15 @@
<thead>
<tr>
<?php
$checkObject = new stdclass();
$checkObject->execution = $execution->id;
$totalEstimate = 0;
$canBatchEdit = common::hasPriv('story', 'batchEdit');
$canBatchClose = common::hasPriv('story', 'batchClose');
$canBatchChangeStage = common::hasPriv('story', 'batchChangeStage');
$canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory');
$canBatchToTask = common::hasPriv('story', 'batchToTask');
$canBatchToTask = common::hasPriv('story', 'batchToTask', $checkObject);
$canBatchAction = ($canBeChanged and ($canBatchEdit or $canBatchClose or $canBatchChangeStage or $canBatchUnlink or $canBatchToTask));
?>
<?php $vars = "executionID={$execution->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
@@ -335,13 +338,14 @@
$actionLink = $this->createLink('story', 'batchEdit', "productID=0&executionID=$execution->id");
echo html::commonButton($lang->edit, "data-form-action='$actionLink' $disabled");
?>
<button type='button' <?php echo $canBatchToTask ? '' : "disabled='disabled'";?> class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
<?php if($canBatchToTask):?>
<button type='button' class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
<ul class='dropdown-menu'>
<?php
$class = $canBatchToTask ? '' : "class='hidden'";
echo "<li $class>" . html::a('#batchToTask', $lang->story->batchToTask, '', "data-toggle='modal' id='batchToTaskButton'") . "</li>";
echo "<li>" . html::a('#batchToTask', $lang->story->batchToTask, '', "data-toggle='modal' id='batchToTaskButton'") . "</li>";
?>
</ul>
<?php endif;?>
</div>
<?php
if($canBatchClose)
+1 -1
View File
@@ -286,7 +286,7 @@ body {margin-bottom: 25px;}
</thead>
<tbody>
<?php foreach($tasks as $task):?>
<tr data-id='<?php echo $task->id;?>' data-status='<?php echo $task->status?>' data-estimate='<?php echo $task->estimate?>' data-consumed='<?php echo $task->consumed?>' data-left='<?php echo $task->left?>'>
<tr <?php if(!empty($task->children)) echo 'class="table-parent" '; ?>data-id='<?php echo $task->id;?>' data-status='<?php echo $task->status?>' data-estimate='<?php echo $task->estimate?>' data-consumed='<?php echo $task->consumed?>' data-left='<?php echo $task->left?>'>
<?php if($this->app->getViewType() == 'xhtml'):?>
<?php
foreach($customFields as $field)
+3 -3
View File
@@ -78,9 +78,9 @@
$checkObject->execution = $executionID;
$canCreateTask = common::hasPriv('task', 'create', $checkObject);
$canBatchCreateTask = common::hasPriv('task', 'batchCreate', $checkObject);
$canCreateBug = common::hasPriv('bug', 'create');
$canBatchCreateBug = common::hasPriv('bug', 'batchCreate');
$canImportBug = common::hasPriv('execution', 'importBug');
$canCreateBug = ($productID and common::hasPriv('bug', 'create'));
$canBatchCreateBug = ($productID and common::hasPriv('bug', 'batchCreate'));
$canImportBug = ($productID and common::hasPriv('execution', 'importBug'));
$canCreateStory = ($productID and common::hasPriv('story', 'create'));
$canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate'));
$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory'));

Some files were not shown because too many files have changed in this diff Show More