Merge branch 'master' into sprint/biz17

This commit is contained in:
qixinzhi
2023-03-06 09:04:52 +08:00
353 changed files with 9864 additions and 2480 deletions
+1 -1
View File
@@ -1 +1 @@
18.1
18.2
+1 -1
View File
@@ -80,7 +80,7 @@ class executionsEntry extends entry
*/
public function post($projectID = 0)
{
$fields = 'project,code,name,begin,end,lifetime,desc,days';
$fields = 'project,code,name,begin,end,lifetime,desc,days,percent,parent';
$this->batchSetPost($fields);
$projectID = $this->param('project', $projectID);
+13
View File
@@ -84,6 +84,19 @@ class hostHeartbeatEntry extends baseEntry
if($heartbeat > 0) $vmData['heartbeat'] = date("Y-m-d H:i:s", $heartbeat);
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('mac')->eq($vm->macAddress)->exec();
if($vm->status == 'running')
{
$node = $this->loadModel('zanode')->getNodeByMac($vm->macAddress);
if(!empty($node))
{
$snaps = $this->loadModel('zanode')->getSnapshotList($node->id);
if(empty($snaps))
{
if($vm->status == 'running') $this->loadModel('zanode')->createDefaultSnapshot($node->id);
}
}
}
}
}
+10 -2
View File
@@ -40,13 +40,21 @@ class hostSubmitEntry extends baseEntry
if(!$id) return $this->sendError(400, 'Secret error.');
$imageInfo = $this->dao->select('`status`,`from`')->from(TABLE_IMAGE)
$imageInfo = $this->dao->select('`status`,`from`', 'name')->from(TABLE_IMAGE)
->where('id')->eq($task)
->fetch();
if(empty($imageInfo)) return $this->sendSuccess(200, 'success');
if($imageInfo->from == 'snapshot' && $imageInfo->status == 'restoring')
{
$image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed';
if(in_array($image->status, array('failed', 'completed'))) $image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed';
}
else if($imageInfo->from == 'snapshot' && $imageInfo->status == 'creating')
{
if($image->status == 'failed')
{
$this->dao->delete()->from(TABLE_IMAGE)->where("id")->eq($task)->exec();
return $this->sendSuccess(200, 'success');
}
}
$this->dao->update(TABLE_IMAGE)->data($image)->where("id")->eq($task)->exec();
+1 -1
View File
@@ -28,7 +28,7 @@ class storyChangeEntry extends entry
$this->batchSetPost($fields, $oldStory);
/* If reviewer is not post, set needNotReview. */
if(empty($this->request('reviewer')))
if(!$this->request('reviewer'))
{
$this->setPost('reviewer', array());
$this->setPost('needNotReview', 1);
+1 -1
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '18.1'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '18.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
+15 -10
View File
@@ -227,7 +227,7 @@ $config->openMethods[] = 'doc.createbasicinfo';
$config->openMethods[] = 'project.createguide';
$config->openMethods[] = 'task.editteam';
$config->openMethods[] = 'feedback.mergeproductmodule';
$config->openMethods[] = 'zanode.nodeList';
$config->openMethods[] = 'zanode.nodelist';
$config->openMethods[] = 'action.restoreStages';
$config->openModules = array();
@@ -407,6 +407,7 @@ $config->objectTables['apistruct'] = TABLE_APISTRUCT;
$config->objectTables['repo'] = TABLE_REPO;
$config->objectTables['dataview'] = TABLE_DATAVIEW;
$config->objectTables['zahost'] = TABLE_ZAHOST;
$config->objectTables['zanode'] = TABLE_ZAHOST;
$config->objectTables['automation'] = TABLE_AUTOMATION;
$config->objectTables['stepResult'] = TABLE_TESTRUN;
@@ -418,9 +419,11 @@ $config->pipelineTypeList = array('gitlab', 'gogs', 'gitea', 'jenkins', 'sonarqu
/* Program privs.*/
$config->programPriv = new stdclass();
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->programPriv->agileplus = $config->programPriv->scrum;
$config->programPriv->waterfallplus = $config->programPriv->waterfall;
$config->waterfallModules = array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'opportunity', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport');
@@ -430,9 +433,11 @@ $config->maxPriValue = '256';
$config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback', 'ticket');
$config->featureGroup = new stdclass();
$config->featureGroup->my = array('score');
$config->featureGroup->product = array('roadmap', 'track', 'UR');
$config->featureGroup->scrum = array();
$config->featureGroup->waterfall = array();
$config->featureGroup->assetlib = array();
$config->featureGroup->other = array('devops', 'kanban');
$config->featureGroup->my = array('score');
$config->featureGroup->product = array('roadmap', 'track', 'UR');
$config->featureGroup->scrum = array();
$config->featureGroup->waterfall = array();
$config->featureGroup->agileplus = array();
$config->featureGroup->waterfallplus = array();
$config->featureGroup->assetlib = array();
$config->featureGroup->other = array('devops', 'kanban');
File diff suppressed because it is too large Load Diff
+2
View File
@@ -260,5 +260,7 @@ INSERT IGNORE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `syst
UPDATE `zt_grouppriv` SET `module` = 'testcase' WHERE `module` = 'story' and `method` = 'zeroCase';
UPDATE `zt_grouppriv` SET `module` = 'product' WHERE `module` = 'story' and `method` = 'track';
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) SELECT `group`, 'product', 'requirement' FROM `zt_grouppriv` WHERE `module` = 'product' AND `method` = 'browse';
ALTER TABLE `zt_job` ADD `lastSyncDate` datetime DEFAULT NULL AFTER `lastTag`;
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('*/5', '*', '*', '*', '*', 'moduleName=compile&methodName=syncCompile', '定时同步构建记录', 'zentao', 1, 'normal', '0000-00-00 00:00:00');
+68
View File
@@ -1 +1,69 @@
DELETE FROM `zt_config` WHERE module = 'datatable' AND section = 'executionAll';
UPDATE `zt_task` SET `assignedTo` = '' WHERE `mode` = 'multi' AND `status` != 'done' AND `status` != 'closed';
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'scrumClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' and `system` = '1' ORDER BY id ASC;
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'agileplusClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' and `system` = '1' ORDER BY id ASC;
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'waterfallplusClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' and `system` = '1' ORDER BY id ASC;
UPDATE `zt_project` AS parent INNER JOIN (select `id`,`parent`,`attribute` from `zt_project` where `parent` != 0 and `type` = 'stage') AS child ON parent.`id` = child.`parent` SET parent.`attribute`='mix' where parent.`grade`=1 and parent.`type`='stage' and parent.`attribute` != child.`attribute`;
REPLACE INTO `zt_grouppriv` (SELECT `group`,`module`,'batchChangeStatus' FROM `zt_grouppriv` WHERE `module` = 'execution' AND `method` = 'batchEdit');
ALTER table `zt_stage` ADD `projectType` varchar(255) NOT NULL DEFAULT '' AFTER `type`;
UPDATE `zt_stage` SET `projectType` = 'waterfall' WHERE `projectType` = '';
REPLACE INTO `zt_stage` (`name`,`percent`,`type`, `projectType`, `createdBy`,`createdDate`,`editedBy`,`editedDate`,`deleted`) VALUES
('需求','10','request','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('设计','10','design','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('开发','50','dev','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('测试','15','qa','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('发布','10','release','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('总结评审','5','review','waterfallplus','admin','2020-02-08 21:08:45','admin','2020-02-12 13:50:27','0');
ALTER table `zt_reviewcl` ADD `type` varchar(255) NOT NULL DEFAULT '' AFTER `category`;
UPDATE `zt_reviewcl` SET `type` = 'waterfall' WHERE `type` = '';
UPDATE `zt_activity` SET `order` = `id` * 5 WHERE `order` = '0';
ALTER table `zt_cmcl` ADD `projectType` varchar(255) NOT NULL DEFAULT '' AFTER `type`;
UPDATE `zt_cmcl` SET `projectType` = 'waterfall' WHERE `projectType` = '';
REPLACE INTO `zt_process` (`model`, `name`, `type`, `abbr`, `desc`, `assignedTo`, `status`, `order`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `deleted`) VALUES
('waterfallplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('waterfallplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
('agileplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
UPDATE `zt_chart` SET `sql` = 'SELECT tt.join as `year`, count(1) as number, tt.name from (\r\nselect \r\nt2.name, YEAR(t1.join) as `join`\r\nfrom zt_team t1 \r\nRIGHT JOIN zt_project t2 on t2.id = t1.root\r\nRIGHT JOIN zt_user t3 on t3.account = t1.account\r\nWHERE t1.type = \'project\'\r\nAND t2.deleted = \'0\'\r\n) tt\r\nGROUP BY tt.`name`, tt.join\r\nORDER BY tt.join, number desc, tt.name' WHERE `id` = '1097';
UPDATE `zt_chart` SET `sql` = 'SELECT tt.join as `year`, count(1) as number, tt.setName from (\r\nselect \r\nYEAR(t1.join) as `join`, t4.name as setName \r\nfrom zt_team t1 \r\nRIGHT JOIN zt_project t2 on t2.id = t1.root\r\nLEFT JOIN zt_project t4 on FIND_IN_SET(t4.id,t2.path) and t4.grade = 1\r\nRIGHT JOIN zt_user t3 on t3.account = t1.account\r\nWHERE t1.type = \'project\'\r\nAND t2.deleted = \'0\'\r\nAND t3.deleted = \'0\'\r\n) tt\r\nGROUP BY tt.setName, tt.join\r\nORDER BY tt.join, number desc, tt.setName' WHERE `id` = '1086';
INSERT IGNORE INTO `zt_config` (`vision`, `owner`, `module`, `key`, `value`) VALUES ('', 'system', 'common', 'setCode', '1');
+1
View File
@@ -0,0 +1 @@
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system','common','','setPercent','1');
+54 -18
View File
@@ -1490,6 +1490,7 @@ CREATE TABLE IF NOT EXISTS `zt_stage` (
`name` varchar(255) NOT NULL,
`percent` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
`projectType` varchar(255) NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
@@ -2162,6 +2163,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1,'custom','project'),
(1,'custom','restore'),
(1,'custom','set'),
(1,'custom','hours'),
(1,'custom','setDefaultConcept'),
(1,'custom','setPublic'),
(1,'custom','setStoryConcept'),
@@ -2754,6 +2756,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(2,'custom','product'),
(2,'custom','restore'),
(2,'custom','set'),
(2,'custom','hours'),
(2,'custom','setPublic'),
(2,'datatable','setGlobal'),
(2,'dept','browse'),
@@ -6384,22 +6387,21 @@ REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) V
('zh-cn', 'custom', 'URSRList', '3', '{\"SRName\":\"\\u8f6f\\u9700\",\"URName\":\"\\u7528\\u9700\"}', '1'),('zh-cn', 'custom', 'URSRList', '4', '{\"SRName\":\"\\u6545\\u4e8b\",\"URName\":\"\\u53f2\\u8bd7\"}', '1'),
('zh-cn', 'custom', 'URSRList', '5', '{\"SRName\":\"\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),
('en', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'),
('en', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'),
('all','stage','typeList','request','需求', '1'),
('all','stage','typeList','design','设计', '1'),
('all','stage','typeList','dev','开发', '1'),
('all','stage','typeList','qa','测试', '1'),
('all','stage','typeList','release','发布', '1'),
('all','stage','typeList','review','总结评审','1'),
('all','stage','typeList','other','其他','1');
('en', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0');
REPLACE INTO `zt_stage` (`name`,`percent`,`type`,`createdBy`,`createdDate`,`editedBy`,`editedDate`,`deleted`) VALUES
('需求','10','request','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('设计','10','design','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('开发','50','dev','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('测试','15','qa','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('发布','10','release','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('总结评审','5','review','admin','2020-02-08 21:08:45','admin','2020-02-12 13:50:27','0');
REPLACE INTO `zt_stage` (`name`,`percent`,`type`,`projectType`,`createdBy`,`createdDate`,`editedBy`,`editedDate`,`deleted`) VALUES
('需求','10','request','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('设计','10','design','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('开发','50','dev','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('测试','15','qa','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('发布','10','release','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('总结评审','5','review','waterfall','admin','2020-02-08 21:08:45','admin','2020-02-12 13:50:27','0'),
('需求','10','request','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('设计','10','design','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('开发','50','dev','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('测试','15','qa','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('发布','10','release','waterfallplus','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
('总结评审','5','review','waterfallplus','admin','2020-02-08 21:08:45','admin','2020-02-12 13:50:27','0');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'hourPoint', '0');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRProduct', '1');
@@ -9703,6 +9705,7 @@ CREATE TABLE IF NOT EXISTS `zt_reviewcl` (
`title` varchar(255) NOT NULL,
`object` char(30) NOT NULL,
`category` char(30) NOT NULL,
`type` varchar(255) NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`order` mediumint(8) DEFAULT '0',
`status` varchar(30) NOT NULL,
@@ -9774,6 +9777,7 @@ CREATE TABLE IF NOT EXISTS `zt_reviewlist` (
CREATE TABLE IF NOT EXISTS `zt_cmcl` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`type` char(30) NOT NULL,
`projectType` varchar(255) NOT NULL,
`title` int(11) NOT NULL,
`contents` text NOT NULL,
`assignedTo` varchar(30) NOT NULL,
@@ -13298,7 +13302,39 @@ REPLACE INTO `zt_process` (`id`, `model`, `name`, `type`, `abbr`, `desc`, `assig
(29, 'scrum', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(28, 'scrum', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(27, 'scrum', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(42, 'scrum', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
(42, 'scrum', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(43, 'waterfallplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(44, 'waterfallplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(45, 'waterfallplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(46, 'waterfallplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(47, 'waterfallplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(48, 'waterfallplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(49, 'waterfallplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(50, 'waterfallplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(51, 'waterfallplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(52, 'waterfallplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(53, 'waterfallplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(54, 'waterfallplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(55, 'waterfallplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(56, 'waterfallplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(57, 'waterfallplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(58, 'waterfallplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(59, 'agileplus', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(60, 'agileplus', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(61, 'agileplus', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(62, 'agileplus', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(63, 'agileplus', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(64, 'agileplus', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(65, 'agileplus', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(66, 'agileplus', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(67, 'agileplus', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(68, 'agileplus', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(69, 'agileplus', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(70, 'agileplus', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(71, 'agileplus', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(72, 'agileplus', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(73, 'agileplus', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(74, 'agileplus', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
REPLACE INTO `zt_activity` (`id`, `process`, `name`, `optional`, `tailorNorm`, `content`, `assignedTo`, `status`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `order`, `deleted`) VALUES
@@ -13840,7 +13876,7 @@ REPLACE INTO `zt_chart` (`id`, `name`, `dimension`, `type`, `group`, `dataset`,
(1082,'年度新增-产品发布次数年度趋势图',1,'line',0,'','','{\r\n \"xaxis\":[{\"field\":\"month\",\"name\":\"月份\",\"group\":\"value\"}],\r\n \"yaxis\":[{\"type\":\"value\",\"field\":\"release\",\"agg\":\"value\",\"name\":\"发布次数\",\"valOrAgg\":\"value\"}\r\n]}','',NULL,'SELECT t1.year, CONCAT(t1.month, \'\') AS `month`, IFNULL(t2.release, 0) AS `release`\r\nFROM (SELECT DISTINCT Year(date) AS `year`, MONTH(date) AS `month` FROM zt_action) AS t1\r\nLEFT JOIN (SELECT YEAR(createdDate) AS `year`, MONTH(createdDate) AS `month`, COUNT(1) AS `release` FROM zt_release WHERE deleted = \'0\' GROUP BY `year`, `month`) AS t2 ON t1.year = t2.year AND t1.month = t2.month\r\nORDER BY `year`, t1.month',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1083,'年度新增-年度投入产出比',1,'line',0,'','','{\r\n \"xaxis\":[{\"field\":\"month\",\"name\":\"月份\",\"group\":\"value\"}],\r\n \"yaxis\":[{\"type\":\"value\",\"field\":\"ratio\",\"agg\":\"value\",\"name\":\"投入产出比\",\"valOrAgg\":\"value\"},\r\n{\"type\":\"value\",\"field\":\"story\",\"agg\":\"value\",\"name\":\"需求交付\",\"valOrAgg\":\"value\"},\r\n{\"type\":\"value\",\"field\":\"consumed\",\"agg\":\"value\",\"name\":\"工时消耗\",\"valOrAgg\":\"value\"}\r\n]}','',NULL,'SELECT t1.`year`, CONCAT(t1.`month`, \'\') AS `month`, IFNULL(t2.story, 0) AS story, IFNULL(t3.consumed, 0) AS consumed, ROUND(IF(IFNULL(t3.consumed, 0) = 0, 0, IFNULL(t2.story, 0) / IFNULL(t3.consumed, 0)), 2) AS ratio\r\nFROM (SELECT YEAR(`date`) AS \'year\', MONTH(`date`) AS \'month\' FROM zt_action GROUP BY `year`,`month`) AS t1\r\nLEFT JOIN (SELECT ROUND(SUM(estimate)) AS story, YEAR(`closedDate`) AS \'year\', MONTH(`closedDate`) AS \'month\' FROM zt_story WHERE deleted = \'0\' AND closedReason = \'done\' AND status = \'closed\' GROUP BY `year`,`month`) AS t2 ON t1.`year` = t2.`year` AND t1.`month` = t2.`month`\r\nLEFT JOIN (SELECT ROUND(SUM(consumed)) as consumed, YEAR(`date`) as \'year\', MONTH(`date`) AS \'month\' FROM zt_effort WHERE deleted = \'0\' GROUP BY `year`,`month`) AS t3 ON t1.`year` = t3.`year` AND t1.`month` = t3.`month`',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1085,'年度排行-项目集-预算投入榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"program\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"budget\",\"agg\":\"value\",\"name\":\"预算\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT \r\n YEAR(t2.openedDate) AS `year`, \r\n t1.id,\r\n t1.name AS program, \r\n ROUND(\r\n SUM(\r\n IFNULL(t2.budget, 0)\r\n ) / 10000, \r\n 2\r\n ) AS budget \r\nFROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_project AS t2 ON FIND_IN_SET(t1.id, t2.path) \r\n AND t2.deleted = \'0\' \r\n AND t2.type = \'project\' \r\nWHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'program\' \r\n AND t1.grade = 1 \r\nGROUP BY \r\n `year`, \r\n id,\r\n program \r\nORDER BY \r\n `year`, \r\n budget DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1086,'年度排行-项目集-人员投入榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"setName\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"number\",\"agg\":\"value\",\"name\":\"人数\",\"valOrAgg\":\"value\"}]}','','','SELECT tt.join as `year`, count(1) as number, tt.setName from (\r\nselect \r\nYEAR(t1.join) as `join`, t4.name as setName \r\nfrom zt_team t1 \r\nRIGHT JOIN zt_project t2 on t2.id = t1.root\r\nLEFT JOIN zt_project t4 on FIND_IN_SET(t4.id,t2.path) and t4.grade = 1\r\nRIGHT JOIN zt_user t3 on t3.account = t1.account\r\nWHERE t1.type = \'project\'\r\n) tt\r\nGROUP BY tt.setName, tt.join\r\nORDER BY tt.join, number desc, tt.setName',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1086,'年度排行-项目集-人员投入榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"setName\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"number\",\"agg\":\"value\",\"name\":\"人数\",\"valOrAgg\":\"value\"}]}','','','SELECT tt.join as `year`, count(1) as number, tt.setName from (\r\nselect \r\nYEAR(t1.join) as `join`, t4.name as setName \r\nfrom zt_team t1 \r\nRIGHT JOIN zt_project t2 on t2.id = t1.root\r\nLEFT JOIN zt_project t4 on FIND_IN_SET(t4.id,t2.path) and t4.grade = 1\r\nRIGHT JOIN zt_user t3 on t3.account = t1.account\r\nWHERE t1.type = \'project\'\r\nAND t2.deleted = \'0\'\r\nAND t3.deleted = \'0\'\r\n) tt\r\nGROUP BY tt.setName, tt.join\r\nORDER BY tt.join, number desc, tt.setName',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1087,'年度排行-项目集-工时消耗榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"program\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"consumed\",\"agg\":\"value\",\"name\":\"消耗工时\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT \r\n YEAR(t5.date) AS `year`, \r\n t1.id,\r\n t1.name AS program, \r\n ROUND(\r\n SUM(t5.consumed), \r\n 2\r\n ) AS consumed \r\nFROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_project AS t2 ON FIND_IN_SET(t1.id, t2.path) \r\n AND t2.deleted = \'0\' \r\n AND t2.type = \'project\' \r\n LEFT JOIN zt_project AS t3 ON t2.id = t3.parent \r\n AND t3.deleted = \'0\' \r\n AND t3.type IN (\'sprint\', \'stage\', \'kanban\') \r\n LEFT JOIN zt_task AS t4 ON t3.id = t4.execution \r\n AND t4.deleted = \'0\' \r\n AND t4.status != \'cancel\' \r\n LEFT JOIN zt_effort AS t5 ON t4.id = t5.objectID \r\n AND t5.deleted = \'0\' \r\n AND t5.objectType = \'task\' \r\nWHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'program\' \r\n AND t1.grade = 1 \r\n AND t5.id IS NOT NULL \r\nGROUP BY \r\n `year`, \r\n id,\r\n program \r\nORDER BY \r\n `year`, \r\n consumed DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1088,'年度排行-项目集-新增需求条目榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"program\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"story\",\"agg\":\"value\",\"name\":\"新增需求条数\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT \r\n YEAR(t3.openedDate) AS `year`,\r\n t1.id, \r\n t1.name AS program, \r\n COUNT(1) AS story \r\nFROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_product AS t2 ON t1.id = t2.program \r\n AND t2.deleted = \'0\' \r\n LEFT JOIN zt_story AS t3 ON t2.id = t3.product \r\n AND t3.deleted = \'0\' \r\nWHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'program\' \r\n AND t1.grade = 1 \r\n AND t3.id IS NOT NULL \r\nGROUP BY \r\n `year`, \r\n id,\r\n program \r\nORDER BY \r\n `year`, \r\n story DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1089,'年度排行-项目集-新增需求规模榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"program\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"story\",\"agg\":\"value\",\"name\":\"新增需求规模\",\"valOrAgg\":\"value\"}]}','','','SELECT \r\n YEAR(t3.openedDate) AS `year`, \r\n t1.id,\r\n t1.name AS program, \r\n ROUND(\r\n SUM(t3.estimate), \r\n 2\r\n ) AS story \r\nFROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_product AS t2 ON t1.id = t2.program \r\n AND t2.deleted = \'0\' \r\n LEFT JOIN zt_story AS t3 ON t2.id = t3.product \r\n AND t3.deleted = \'0\' \r\nWHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'program\' \r\n AND t1.grade = 1 \r\n AND t3.id IS NOT NULL \r\nGROUP BY \r\n `year`,\r\n id, \r\n program \r\nORDER BY \r\n `year`, \r\n story DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
@@ -13850,7 +13886,7 @@ REPLACE INTO `zt_chart` (`id`, `name`, `dimension`, `type`, `group`, `dataset`,
(1093,'年度排行-项目集-修复Bug条目榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"program\",\"name\":\"项目集\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"bug\",\"agg\":\"value\",\"name\":\"修复Bug条目\",\"valOrAgg\":\"value\"}]}','','','SELECT \r\n YEAR(t3.closedDate) AS `year`,\r\n t1.id, \r\n t1.name AS program, \r\n COUNT(1) AS bug \r\nFROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_product AS t2 ON t1.id = t2.program \r\n AND t2.deleted = \'0\' \r\n LEFT JOIN zt_bug AS t3 ON t2.id = t3.product \r\n AND t3.deleted = \'0\' \r\n AND t3.resolution = \'fixed\' \r\n AND t3.status = \'closed\' \r\nWHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'program\' \r\n AND t1.grade = 1 \r\n AND t3.id IS NOT NULL \r\nGROUP BY \r\n `year`, \r\n id,\r\n program \r\nORDER BY \r\n `year`, \r\n bug DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1094,'年度排行-项目-工期榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"name\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"duration\",\"agg\":\"value\",\"name\":\"工期\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT `year`, id,name,status,realBegan,realEnd,IF(status = \'closed\', DATEDIFF(realEnd, realBegan), DATEDIFF(NOW(),realBegan)) as duration\r\nFROM (SELECT DISTINCT YEAR(`date`) as \'year\' FROM zt_action) AS t1\r\nLEFT JOIN zt_project AS t2 ON 1 = 1 WHERE deleted = \'0\' AND type = \'project\' AND YEAR(realBegan) <= `year` AND LEFT(realBegan, 4) != \'0000\' AND (status =\'doing\' OR (status = \'suspended\' AND YEAR(suspendedDate) >= `year`) OR (status = \'closed\' AND YEAR(realEnd) >= `year`)) HAVING 1=1 ORDER BY `year`, duration desc',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1096,'年度排行-项目-工期偏差榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"name\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"duration\",\"agg\":\"value\",\"name\":\"工期\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT `year`, id,name,status,`begin`,`end`,realBegan,realEnd,\nROUND((IF(LEFT(realEnd,4) != \'0000\', DATEDIFF(realEnd, realBegan), DATEDIFF(NOW(),realBegan)) - DATEDIFF(`end`, `begin`)) / DATEDIFF(`end`,`begin`) * 100) as duration\nFROM (SELECT DISTINCT YEAR(`date`) as \'year\' FROM zt_action) AS t1\nLEFT JOIN zt_project AS t2 ON 1 = 1 \nWHERE deleted = \'0\' AND type = \'project\'\nAND YEAR(realBegan) <= `year` AND LEFT(realBegan, 4) != \'0000\'\nAND (YEAR(realEnd) >= `year` OR LEFT(realEnd, 4) = \'0000\') AND YEAR(`end`) != \'2059\'\nHAVING 1=1\nORDER BY duration ASC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1097,'年度排行-项目-人员投入榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"name\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"number\",\"agg\":\"value\",\"name\":\"人数\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT tt.join as `year`, count(1) as number, tt.name from (\r\nselect \r\nt2.name, YEAR(t1.join) as `join`\r\nfrom zt_team t1 \r\nRIGHT JOIN zt_project t2 on t2.id = t1.root\r\nRIGHT JOIN zt_user t3 on t3.account = t1.account\r\nWHERE t1.type = \'project\'\r\n) tt\r\nGROUP BY tt.`name`, tt.join\r\nORDER BY tt.join, number desc, tt.name',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1097,'年度排行-项目-人员投入榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"name\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"number\",\"agg\":\"value\",\"name\":\"人数\",\"valOrAgg\":\"value\"}]}','','','SELECT tt.join as `year`, count(1) as number, tt.name from (\r\nselect \r\nt2.name, YEAR(t1.join) as `join`\r\nfrom zt_team t1 \r\nRIGHT JOIN zt_project t2 on t2.id = t1.root\r\nRIGHT JOIN zt_user t3 on t3.account = t1.account\r\nWHERE t1.type = \'project\'\r\nAND t2.deleted = \'0\'\r\n) tt\r\nGROUP BY tt.`name`, tt.join\r\nORDER BY tt.join, number desc, tt.name',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1098,'年度排行-项目-工时消耗榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"project\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"consumed\",\"agg\":\"value\",\"name\":\"消耗工时\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT \r\n YEAR(t4.date) AS `year`,\r\n t1.id, \r\n t1.name AS project, \r\n ROUND(\r\n SUM(t4.consumed), \r\n 2\r\n ) AS consumed \r\nFROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_project AS t2 ON t1.id = t2.parent \r\n AND t2.deleted = \'0\' \r\n AND t2.type IN (\'sprint\', \'stage\', \'kanban\') \r\n LEFT JOIN zt_task AS t3 ON t2.id = t3.execution \r\n AND t3.deleted = \'0\' \r\n AND t3.status != \'cancel\' \r\n LEFT JOIN zt_effort AS t4 ON t3.id = t4.objectID \r\n AND t4.deleted = \'0\' \r\n AND t4.objectType = \'task\' \r\nWHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'project\' \r\n AND t4.id IS NOT NULL \r\nGROUP BY \r\n `year`, \r\n id,\r\n project \r\nORDER BY \r\n `year`, \r\n consumed DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1099,'年度排行-项目-完成需求条目榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"project\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"story\",\"agg\":\"value\",\"name\":\"完成需求条目\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT \r\n YEAR(t1.closedDate) AS `year`, \r\n t1.id, \r\n t1.project, \r\n COUNT(1) AS story \r\nFROM \r\n (\r\n SELECT \r\n DISTINCT t1.id, \r\n t1.name AS project, \r\n t4.id AS story, \r\n t4.closedDate \r\n FROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_project AS t2 ON t1.id = t2.parent \r\n AND t2.deleted = \'0\' \r\n AND t2.type IN (\'sprint\', \'stage\', \'kanban\') \r\n LEFT JOIN zt_projectstory AS t3 ON t2.id = t3.project \r\n LEFT JOIN zt_story AS t4 ON t3.story = t4.id \r\n AND t4.deleted = \'0\' \r\n AND t4.closedReason = \'done\' \r\n WHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'project\' \r\n AND t4.id IS NOT NULL\r\n ) AS t1 \r\nGROUP BY \r\n `year`, \r\n id, \r\n project \r\nORDER BY \r\n `year`, \r\n story DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
(1100,'年度排行-项目-完成需求规模榜',1,'bar',0,'','','{\"xaxis\":[{\"field\":\"project\",\"name\":\"项目\"}],\"yaxis\":[{\"type\":\"value\",\"field\":\"story\",\"agg\":\"value\",\"name\":\"完成需求规模\",\"valOrAgg\":\"value\"}]}','',NULL,'SELECT \r\n YEAR(t1.closedDate) AS `year`, \r\n t1.id, \r\n t1.project, \r\n ROUND(\r\n SUM(t1.estimate), \r\n 2\r\n ) AS story \r\nFROM \r\n (\r\n SELECT \r\n DISTINCT t1.id, \r\n t1.name AS project, \r\n t4.id AS story, \r\n t4.estimate, \r\n t4.closedDate \r\n FROM \r\n zt_project AS t1 \r\n LEFT JOIN zt_project AS t2 ON t1.id = t2.parent \r\n AND t2.deleted = \'0\' \r\n AND t2.type IN (\'sprint\', \'stage\', \'kanban\') \r\n LEFT JOIN zt_projectstory AS t3 ON t2.id = t3.project \r\n LEFT JOIN zt_story AS t4 ON t3.story = t4.id \r\n AND t4.deleted = \'0\' \r\n AND t4.closedReason = \'done\' \r\n WHERE \r\n t1.deleted = \'0\' \r\n AND t1.type = \'project\' \r\n AND t4.id IS NOT NULL\r\n ) AS t1 \r\nGROUP BY \r\n `year`, \r\n id, \r\n project \r\nORDER BY \r\n `year`, \r\n story DESC',1,'','','0000-00-00 00:00:00','','0000-00-00 00:00:00',0),
-6
View File
@@ -1,6 +0,0 @@
update `zt_task` set `assignedTo` = '' where `mode` = 'multi' and `status` != 'done' and `status` != 'closed';
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'scrumClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' ORDER BY id ASC;
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'agileplusClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' ORDER BY id ASC;
UPDATE `zt_project` AS parent INNER JOIN (select `id`,`parent`,`attribute` from `zt_project` where `parent` != 0 and `type` = 'stage') AS child ON parent.`id` = child.`parent` SET parent.`attribute`='mix' where parent.`grade`=1 and parent.`type`='stage' and parent.`attribute` != child.`attribute`;
+229
View File
@@ -1,3 +1,232 @@
2023-02-27 18.2
完成的需求
开源版:
41729 按指派人搜索时,支持搜索多人并行任务
41730 待处理中过滤掉我已经完成的多人并行任务
41731 多人并行任务全部完成后指派给创建人
41732 编辑任务时,父/子任务不能修改为多人任务
41817 创建项目弹窗增加融合敏捷项目
41821 融合敏捷项目的迭代菜单下可以创建看板
41824 创建融合敏捷项目时,能复制融合敏捷项目的信息
41825 创建执行时,能复制融合敏捷项目的执行的信息
41829 融合敏捷项目的创建执行页面,增加方法字段
41830 批量编辑迭代信息页面,增加方法字段
41832 迭代列表导出增加方法字段
41833 后台全局设置增加融合敏捷设置
41834 后台融合敏捷设置下增加QA设置
41835 后台融合敏捷设置下增加过程设置
41940 后台过程设置的分类项设置,不同模型管理自己的分类项
41952 轻量级模式增加融合敏捷项目入口
41826 创建Bug时执行只能选择叶子执行
41831 创建问题、风险、机会时只能选择叶子执行
41839 瀑布项目阶段列表支持无限层级
41865 创建版本时只能选择叶子执行
41867 提交测试单时只能选择叶子执行
41870 瀑布项目的甘特图列表支持无限层级
41872 执行列表支持无限层级
41877 瀑布模型的里程碑报告统计该阶段下所有数据
41878 瀑布项目支持创建无限级阶段
41889 阶段编辑页面支持修改父阶段
41891 阶段类型增加“综合”
41907 瀑布项目创建任务时所属执行只能选择叶子执行
41911 通用看板导入执行时可以选择父执行或子执行
41912 创建执行文档库时支持选择父执行或子执行
41913 执行文档库中2.5级菜单支持选择父执行或子执行
41915 新增日志时只能选择叶子执行
41957 代码模块中维护所属执行时只能选择叶子执行
41961 代码的评审模块中维护所属执行时只能选择叶子执行
41968 回收站内父阶段未删除时才能恢复子阶段
42011 子阶段增加阶段类型字段
42017 父阶段阶段类型修改后,子阶段类型同步变更
42019 无限级阶段的阶段进度计算规则
42212 宿主机重装服务后可正常操作执行节点
42213 初始化中的执行节点只能进行远程操作
42214 快照状态显示优化
42215 创建执行节点的初始快照
42216 加载或刷新宿主机详情页时清空服务状态文本
42217 加载或刷新执行节点详情页时清空服务状态文本
41743 后台首页内容定义
41755 功能配置页的二级导航定义
41756 后台首页设置区块调整
41759 后台首页插件区块内容
41760 后台首页公开课区块的内容
41761 后台首页官方公众号区块的内容
41768 后台配置页增加1.5级导航切换功能
41774 私有部署时后台首页内容调整
41777 后台模型配置页面结构调整
41791 后台通知页面结构调整
41793 后台数据导入页面定义
41794 后台系统设置页面的结构调整
41797 后台二次开发页面的结构调整
41837 非中文版本后台首页内容调整
41745 功能配置下的地盘中新增待办和区块的Tab项
41746 功能配置下的产品中新增Tab项
41747 功能配置下的执行中新增Tab项
41748 功能配置下的测试中新增Tab项
41749 新增功能配置下的看板模块
41750 功能配置下的文档中新增必填项设置的字段及内容
41751 新增功能配置下的反馈模块
41752 将后台的审批移至功能配置下做为审批模块导航
41753 将后台全局设置中的度量移至功能配置中做为度量模块的设置入口
41754 新增功能配置下的会议室模块
41758 后台首页禅道信息区块内容
41766 调整二级页面配置项详情页面的布局和结构
41773 新增功能配置下的用户模块
41775 后台人员配置页面结构调整
41776 后台功能开关页面结构调整
41790 后台模型配置中瀑布模型的配置项定义
41795 后台系统中聊天页面的排版调整
41812 后台文档模板页面内容补充并调整结构
41942 运营界面的后台功能配置中,新增的项目导航内容定义
41955 调整后台基线模块的权限配置
41965 将后台自定义的语言项改为配置
42006 禅道补丁、新闻动态、公开课和禅道升级信息的接口
41869 创建融合瀑布项目时,能复制瀑布项目和融合瀑布项目的信息
41871 创建执行时,能复制融合瀑布项目的执行的信息
41895 后台全局设置增加融合瀑布设置
41896 后台融合瀑布设置下增加阶段设置
41897 后台融合瀑布设置下增加设计设置
41898 后台融合瀑布设置下增加QA设置
41899 后台融合瀑布设置下增加配置设置
41900 后台融合瀑布设置下增加过程设置
41901 后台融合瀑布设置下增加评审设置
41902 更新API接口
41906 后台系统模式下,增加融合敏捷和融合瀑布
41941 后台系统功能设置,增加融合敏捷和融合瀑布
42100 瀑布项目的甘特图列表支持迭代和看板的展示
42194 融合敏捷项目复制时,可以复制敏捷项目信息
42196 融合敏捷项目创建执行时,能复制敏捷项目的执行的信息
42360 阶段的所属计划可以编辑修改
42501 融合敏捷项目创建执行页面增加提示语
42502 融合瀑布项目创建子阶段页面增加提示语
42517 多层级阶段的瀑布项目。在项目看板中,展示了第一层级阶段
42542 融合敏捷项目下,迭代和看板支持互相转入任务
42543 融合瀑布项目下,叶子节点的执行支持互相转入任务
39290 瀑布项目的阶段支持排序
41769 执行统计区块仅展示叶子层级的执行数据
41803 执行总览区块统计父子层级汇总的数据
41804 执行列表区块展示父子层级汇总的数据
41815 项目集看板中的执行只展示叶子节点的执行
41816 产品看板中的执行只展示叶子节点的执行
41828 瀑布项目的项目计划区块仅统计一级阶段的数据
41868 创建项目弹窗增加融合瀑布项目
41875 修改阶段状态时,同步调整父子阶段的状态
41892 融合瀑布项目阶段细分时,可以细分为迭代和看板
41893 批量编辑阶段信息页面,增加方法字段
41894 阶段列表导出增加方法字段
41917 复制瀑布项目时支持复制无限级阶段
42037 组织的日志中的执行只展示叶子节点的执行
42038 组织的动态中的执行展示父执行和子执行
42052 批量编辑无限级阶段信息时需要增加校验信息
42088 融合瀑布项目迭代和看板的编辑页面增加父阶段
42089 融合瀑布项目迭代和看板的的产品不允许编辑
42182 剩余类型的迭代/看板的功能与阶段保持一致
42193 执行1.5级菜单根据层级展示
42195 设计类型的阶段增加研发需求菜单及功能
42197 测试类型的阶段增加代码的菜单及功能
42231 阶段进行操作时,同步调整父子阶段的状态
42176 设计类型的迭代/看板的功能与阶段保持一致
42175 需求/总结评审类型的迭代/看板的功能与阶段保持一致
修复的Bug
开源版:
32397 地盘待处理任务搜索界面报错
企业版:
18695 bug重新步骤有图片,导出mht没有图片
22568 特殊情况下,上线中不显示添加的计划
23227 导出xls格式模板部门字段点击下拉控件无反应
23588 反馈列表批量编辑时,所属产品作为必填项为空时可以保存
24026 导出的word中显示多余的空行
24733 反馈转待办页面,提示关联编号不能为空
24881 没有详情权限时,历史记录中不应展示链接
24897 切换左侧筛选标签,上方标签统计数字消失
24932 自定义切换语言未选中“适用当前语言”
24935 只有默认反馈关闭原因,切换到法语,语言项有问题
24944 没有详情页权限,点击历史记录提示没权限
24997 追问时提示回复内容不能为空
25008 需求详情页弹窗,撤销评审后变空白页了
25010 任务列表详情页弹窗,返回按钮点击没反应
25017 导出用例时<>会被转义为&lt;&gt;
25082 用例导入是带有<>符号时显示异常
25104 反馈指派后,指派人在反馈列表看不到指派的反馈
25183 测试用例下从用例库导入的用例未同步到项目测试用例下
25251 代码评审详情页转任务时提示信息不合理
25442 账号页面搜索条件选择由谁添加/编辑时未列出系统用户
25468 反馈列表,创建人字段鼠标悬浮不能显示title
25475 法语下创建FAQ按钮语言项错误
25853 用例详情页显示了导入用例库按钮
25883 地盘-日志,点击任意日期添加日志遮罩无反应
26140 wiki文档搜索结果错误
26147 法语下切换研发综合界面和迅捷界面报错
26227 一个Bug有多个附件时,导出后多个附件显示在多列了
26341 用户需求列表导出显示了“所属计划”字段
26422 数据富文本字段中带有表格时,导出xlsx表格中列宽太宽
26427 导出项目下研发需求模块和计划显示不正确
26432 导入需求评审人可以选择所有产品成员
26435 导出的用例库模板中显示了产品的所属模块
26436 测试用例库导出模板没有包含模块的系统数据
26439 项目测试下导入的用例只显示了测试视图下的用例列表中
26440 导出任务,来源Bug字段只显示了Bug的id
26444 工作流导出模板后导入后,提示没有有效数据
26446 新增工作流下载模板,里面的字段不对
26552 文档的上一篇按钮显示缺失
26568 用例导出特殊字符会异常
26680 执行甘特图中按钮无图标
26855 导入时,关掉错误提示弹框,导入按钮置灰
27039 批量编辑反馈时指派给显示了closed
27113 英文下反馈标签栏换行显示
27119 反馈转待办,完成待办后动态中缺少语言项
27127 编辑执行和创建执行可用工作日逻辑不一致
27207 创建反馈时产品的下拉列表显示顺序和反馈权限列表顺序不一致
27322 导出反馈数据,数据中字段没有进行重新排序
27571 执行视图分组视图导出的任务列表相关研发需求丢失
28630 反馈列表选择产品后,创建反馈时没有显示已选产品
28680 创建反馈页面选择产品下拉菜单中产品顺序不正确
28722 编辑反馈时没有显示来源公司字段
28773 产品模块下的反馈转研发需求/用户需求时,模块没有自动带出来
28780 新增日志时工作内容输入空格可以保存成功
28804 工单详情页来源字段处,反馈编号前建议增加“#”
28869 导入用例相关研发需求换行显示
28890 反馈列表操作按钮换行
32093 影响版本下拉单选多选不固定
32098 反馈同步产品模块,反馈模块太长不能完全显示
旗舰版:
24152 新增自定义严重程度时,QA执行检查时严重程度显示被遮挡
24499 添加一个风险区块按照状态倒叙排序,默认排序与手动状态倒叙排序不一致
24525 审批流中选择多个审批人,发起审批时只显示第一个
24577 审批流中审批类型为角色,发起审批时不显示
24723 会议生成的日程没有创建日程的历史记录
24816 德语法语下资产库操作栏菜单显示不全
24872 资产库预览文档时切换BIG5格式不成功
25127 评审的问题列表选择评审项后,评审项显示不完整
25477 过程名称很长时在左侧检查对象区块中显示问题
25654 QA质量保证计划再次编辑时,不能看到上次填写的备注
25966 点击上一步回到基础信息页面后,部分信息显示不正确
25976 阶段的访问控制改为私有后,当前用户也看不到该阶段了
26041 会议记录页面只显示了在该页面上传的附件
26288 待处理/贡献、组织团队下的风险列表中风险系数和优先级样式未调整
26474 升级禅道15系列介绍页面视频下方的空白建议调小点
26577 基线评审,概要设计名称中含有“-”,获取系统数据会有问题
26615 工期估算页面展示的界面错误导致无法保存
27355 质量保证计划检查结果为否,未校验严重程度是否为空
29011 问题详情页未指派样式建议优化
29169 费用估算列表的阶段字段换行显示
29222 分页查看执行附件库时,跳转到文档执行库下
29413 费用估算列表页中阶段名称换行了
30351 工作流增加富文本字段,导出后带有html标签,可读性差
30843 旗舰版瀑布项目阶段排序后,甘特图不会同步
30912 设置阶段时,输出选择多项后整个页面样式不友好
31059 火狐浏览器设计审批流页面添加审批节点后页面显示不全不能滑动显示
31414 审批流浏览器通知,有多条重复标题
31425 浏览器通知中未显示名称
31443 任务删除时,同时删除依赖关系
31941 正在审批的流程显示了上一次审批节点的结果
31943 项目型项目发起研发需求评审,评审页面无结构化评审内容
31957 回收站中点击评审问题,详情页中有解决按钮
31962 删除的文档/活动没有标记已删除
31964 复制项目型项目提示关联产品或创建产品
31996 后台过程列表执行搜索后,模型的二级导航下拉菜单高亮了两个
32117 配置项删除按钮与系统的不一致
2023-02-08 18.1
完成的需求
开源版:
+3 -3
View File
@@ -11,13 +11,13 @@ Z PUBLIC LICENSE(ZPL) 1.2
Authorization
Z PUBLIC LICENSE, also known as ZPL Agreement, is drafted by EasyCorp(www.easycorp.ltd).
Z PUBLIC LICENSE, also known as ZPL Agreement, is drafted by ZenTao Software(www.easycorp.ltd).
Anyone can use the agreement to publish open source software, and modify the blank in the following text of the agreement accordingly.
No other text of the agreement shall be changed. EasyCorp has the final interpretation of the terms in the agreement.
No other text of the agreement shall be changed. ZenTao Software has the final interpretation of the terms in the agreement.
Preface
ZenTao ALM (Hereinafter referred to as "the software") developed by EasyCorp (www.easycorp.ltd) (hereinafter referred to I). I'm entitled to all copyright of the software.
ZenTao ALM (Hereinafter referred to as "the software") developed by ZenTao Software (www.easycorp.ltd) (hereinafter referred to I). I'm entitled to all copyright of the software.
The software is released as open source software. You are authorized to use the software as long as you are in compliance with this agreement.
By installation of the software, you agree that a contractual relationship between you and me is automatically established.
You are obliged to fully comply with all the terms of this agreement unless you choose to stop using the software or you have signed additional agreement with me.
+3 -3
View File
@@ -2,13 +2,13 @@ Z PUBLIC LICENSE 1.2
Authorization
Z PUBLIC LICENSE, also known as ZPL Agreement, is drafted by EasyCorp(www.easycorp.ltd).
Z PUBLIC LICENSE, also known as ZPL Agreement, is drafted by ZenTao Software(www.easycorp.ltd).
Anyone can use the agreement to publish open source software, and modify the blank in the following text of the agreement accordingly.
No other text of the agreement shall be changed. EasyCorp has the final interpretation of the terms in the agreement.
No other text of the agreement shall be changed. ZenTao Software has the final interpretation of the terms in the agreement.
Preface
ZenTao LITE (Hereinafter referred to as "the software") developed by EasyCorp (www.easycorp.ltd) (hereinafter referred to I). I'm entitled to all copyright of the software.
ZenTao LITE (Hereinafter referred to as "the software") developed by ZenTao Software (www.easycorp.ltd) (hereinafter referred to I). I'm entitled to all copyright of the software.
The software is released as open source software. You are authorized to use the software as long as you are in compliance with this agreement.
By installation of the software, you agree that a contractual relationship between you and me is automatically established.
You are obliged to fully comply with all the terms of this agreement unless you choose to stop using the software or you have signed additional agreement with me.
+1 -1
View File
@@ -649,7 +649,7 @@ $lang->resource->custom = new stdclass();
$lang->resource->custom->index = 'index';
$lang->resource->custom->set = 'set';
$lang->resource->custom->product = 'productName';
$lang->resource->custom->execution = 'execution';
$lang->resource->custom->execution = 'executionCommon';
$lang->resource->custom->required = 'required';
$lang->resource->custom->restore = 'restore';
$lang->resource->custom->flow = 'flow';
+3 -3
View File
@@ -11,11 +11,11 @@ enterprises. It enables every department and every employee in the company to ma
EOT;
$lang->install->links = <<<EOT
ZenTao Lite is developed by <strong><a href='https://en.easysoft.ltd' target='_blank' class='text-danger'>EasyCorp</a></strong>.
ZenTao Lite is developed by <strong><a href='https://en.easysoft.ltd' target='_blank' class='text-danger'>ZenTao Software</a></strong>.
Official Website: <a href='https://www.zentao.pm' target='_blank'>https://www.zentao.pm</a>
Technical Support: <a href='https://www.zentao.pm/forum/' target='_blank'>https://www.zentao.pm/forum/</a>
LinkedIn: <a href='https://www.linkedin.com/company/1156596/' target='_blank'>EasyCorp</a>
Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>EasyCorp</a>
LinkedIn: <a href='https://www.linkedin.com/company/1156596/' target='_blank'>ZenTao Software</a>
Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>ZenTao Software</a>
Twitter: <a href='https://twitter.com/ZentaoA' target='_blank'>ZenTao Lite</a>
+3 -3
View File
@@ -11,11 +11,11 @@ enterprises. It enables every department and every employee in the company to ma
EOT;
$lang->install->links = <<<EOT
ZenTao Lite is developed by <strong><a href='https://en.easysoft.ltd' target='_blank' class='text-danger'>EasyCorp</a></strong>.
ZenTao Lite is developed by <strong><a href='https://en.easysoft.ltd' target='_blank' class='text-danger'>ZenTao Software</a></strong>.
Official Website: <a href='https://www.zentao.pm' target='_blank'>https://www.zentao.pm</a>
Technical Support: <a href='https://www.zentao.pm/forum/' target='_blank'>https://www.zentao.pm/forum/</a>
LinkedIn: <a href='https://www.linkedin.com/company/1156596/' target='_blank'>EasyCorp</a>
Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>EasyCorp</a>
LinkedIn: <a href='https://www.linkedin.com/company/1156596/' target='_blank'>ZenTao Software</a>
Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>ZenTao Software</a>
Twitter: <a href='https://twitter.com/ZentaoA' target='_blank'>ZenTao Lite</a>
+3 -3
View File
@@ -11,11 +11,11 @@ enterprises. It enables every department and every employee in the company to ma
EOT;
$lang->install->links = <<<EOT
ZenTao Lite is developed by <strong><a href='https://en.easysoft.ltd' target='_blank' class='text-danger'>EasyCorp</a></strong>.
ZenTao Lite is developed by <strong><a href='https://en.easysoft.ltd' target='_blank' class='text-danger'>ZenTao Software</a></strong>.
Official Website: <a href='https://www.zentao.pm' target='_blank'>https://www.zentao.pm</a>
Technical Support: <a href='https://www.zentao.pm/forum/' target='_blank'>https://www.zentao.pm/forum/</a>
LinkedIn: <a href='https://www.linkedin.com/company/1156596/' target='_blank'>EasyCorp</a>
Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>EasyCorp</a>
LinkedIn: <a href='https://www.linkedin.com/company/1156596/' target='_blank'>ZenTao Software</a>
Facebook: <a href='https://www.facebook.com/natureeasysoft' target='_blank'>ZenTao Software</a>
Twitter: <a href='https://twitter.com/ZentaoA' target='_blank'>ZenTao Lite</a>
@@ -40,7 +40,7 @@
<th><?php echo $lang->project->name;?></th>
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
</tr>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<?php if(isset($config->setCode) and $config->setCode == 1):?>
<tr>
<th><?php echo $lang->project->code;?></th>
<td><?php echo html::input('code', '', "class='form-control' required");?></td>
@@ -36,7 +36,7 @@
}
unset($visibleFields['module']);
?>
<form method='post' class='load-indicator main-form' enctype='multipart/form-data' target='hiddenwin' id="batchCreateForm">
<form method='post' class='load-indicator main-form form-ajax' enctype='multipart/form-data' id="batchCreateForm">
<div class="table-responsive">
<table class="table table-form">
<thead>
+8 -8
View File
@@ -96,7 +96,7 @@ class helper extends baseHelper
}
else
{
if($feature == 'scrum' or $feature == 'waterfall') return strpos(",$config->disabledFeatures,", ",{$feature},") === false;
if(in_array($feature, array('scrum', 'waterfall', 'agileplus', 'waterfallplus'))) return strpos(",$config->disabledFeatures,", ",{$feature},") === false;
$hasFeature = false;
$canConfigFeature = false;
@@ -107,7 +107,7 @@ class helper extends baseHelper
if($feature == $group or $feature == $module)
{
$canConfigFeature = true;
if($group == 'scrum' or $group == 'waterfall')
if(in_array($group, array('scrum', 'waterfall', 'agileplus', 'waterfallplus')))
{
if(helper::hasFeature("{$group}") and helper::hasFeature("{$group}_{$module}")) $hasFeature = true;
}
@@ -339,12 +339,12 @@ class helper extends baseHelper
$dateInterval->hour = $interval->format('%H');
$dateInterval->minute = $interval->format('%i');
$dateInterval->secound = $interval->format('%s');
$dateInterval->year = trim($dateInterval->year, '0');
$dateInterval->month = trim($dateInterval->month, '0');
$dateInterval->day = trim($dateInterval->day, '0');
$dateInterval->hour = trim($dateInterval->hour, '0');
$dateInterval->minute = trim($dateInterval->minute, '0');
$dateInterval->secound = trim($dateInterval->secound, '0');
$dateInterval->year = $dateInterval->year == '00' ? 0 : ltrim($dateInterval->year, '0');
$dateInterval->month = $dateInterval->month == '00' ? 0 : ltrim($dateInterval->month, '0');
$dateInterval->day = $dateInterval->day == '00' ? 0 : ltrim($dateInterval->day, '0');
$dateInterval->hour = $dateInterval->hour == '00' ? 0 : ltrim($dateInterval->hour, '0');
$dateInterval->minute = $dateInterval->minute == '00' ? 0 : ltrim($dateInterval->minute, '0');
$dateInterval->secound = $dateInterval->secound == '00' ? 0 : ltrim($dateInterval->secound, '0');
}
return $dateInterval;
}
+53
View File
@@ -0,0 +1,53 @@
<?php
/**
* The cache library of zentaopms.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Lu Fei <lufei@easycorp.ltd>
* @package cache
* @link http://www.zentao.net
*/
helper::import(dirname(__FILE__) . DS . 'simple-cache' . DS . 'CacheInterface.php');
helper::import(dirname(__FILE__) . DS . 'simple-cache' . DS . 'CacheException.php');
helper::import(dirname(__FILE__) . DS . 'simple-cache' . DS . 'InvalidArgumentException.php');
helper::import(dirname(__FILE__) . DS . 'driver' . DS . 'ApcuDriver.php');
helper::import(dirname(__FILE__) . DS . 'driver' . DS . 'YacDriver.php');
use ZenTao\Cache\SimpleCache\InvalidArgumentException;
class cache
{
/**
* @var ZenTao\Cache\SimpleCache\CacheInterface
*/
protected $client;
public function __construct($driver = 'Apcu', $namespace = '', $defaultLifetime = 0)
{
$driver = ucfirst(strtolower($driver));
switch($driver)
{
case 'Apcu':
$className = 'ZenTao\Cache\Driver\ApcuDriver';
break;
case 'Yac':
$className = 'ZenTao\Cache\Driver\YacDriver';
break;
default:
throw new InvalidArgumentException("Driver {$driver} is not supported.");
}
if(!extension_loaded($driver)) throw new InvalidArgumentException("Driver ext-{$driver} is not loaded.");
$this->client = new $className($namespace, $defaultLifetime);
}
public function __call($name, $arguments)
{
if(!method_exists($this->client, $name)) throw new InvalidArgumentException("Method {$name} does not exist.");
return call_user_func_array(array($this->client, $name), $arguments);
}
}
+173
View File
@@ -0,0 +1,173 @@
<?php
/**
* The cache library of zentaopms.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Lu Fei <lufei@easycorp.ltd>
* @package cache
* @link http://www.zentao.net
*/
namespace ZenTao\Cache\Driver;
use ZenTao\Cache\SimpleCache\CacheInterface;
use ZenTao\Cache\SimpleCache\InvalidArgumentException;
class ApcuDriver implements CacheInterface
{
/**
* @var string
*/
private $namespace;
/**
* @var int
*/
private $defaultLifetime;
public function __construct($namespace = '', $defaultLifetime = 0)
{
$this->namespace = $namespace;
$this->defaultLifetime = $defaultLifetime;
}
public function get($key, $default = null)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
$value = apcu_fetch($key, $success);
return $success === false ? $default : $value;
}
public function set($key, $value, $ttl = null)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
return apcu_store($key, $value, (int) $ttl);
}
public function delete($key)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
return apcu_delete($key);
}
public function clear()
{
return apcu_clear_cache();
}
public function getMultiple($keys, $default = null)
{
$this->assertKeyNames($keys);
$keys = $this->buildKeyNames($keys);
$result = apcu_fetch($keys);
if(!is_null($default) && is_array($result) && count($keys) > count($result))
{
$notFoundKeys = array_diff($keys, array_keys($result));
$result = array_merge($result, array_fill_keys($notFoundKeys, $default));
}
$mappedResult = array();
foreach($result as $key => $value)
{
$key = preg_replace("/^$this->namespace/", '', $key);
$mappedResult[$key] = $value;
}
return $mappedResult;
}
public function setMultiple($values, $ttl = null)
{
$this->assertKeyNames(array_keys($values));
$mappedByNamespaceValues = array();
foreach($values as $key => $value)
{
$mappedByNamespaceValues[$this->buildKeyName($key)] = $value;
}
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
$result = apcu_store($mappedByNamespaceValues, (int) $ttl);
return $result === true ? true : (is_array($result) && count($result) == 0 ? true : false);
}
public function deleteMultiple($keys)
{
$this->assertKeyNames($keys);
$keys = $this->buildKeyNames($keys);
$result = apcu_delete($keys);
return count($result) === count($keys) ? false : true;
}
public function has($key)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
return (bool) apcu_exists($key);
}
/**
* @param string $key
*
* @return string
*/
private function buildKeyName($key)
{
return $this->namespace . $key;
}
/**
* @param string[] $keys
*
* @return string[]
*/
private function buildKeyNames(array $keys)
{
return array_map(function($key) {
return $this->buildKeyName($key);
}, $keys);
}
/**
* @param mixed $key
*
* @throws InvalidArgumentException
*/
private function assertKeyName($key)
{
if(!is_scalar($key) || is_bool($key)) throw new InvalidArgumentException();
}
/**
* @param string[] $keys
*
* @throws InvalidArgumentException
*/
private function assertKeyNames(array $keys)
{
array_map(function ($value) {
$this->assertKeyName($value);
}, $keys);
}
}
+197
View File
@@ -0,0 +1,197 @@
<?php
/**
* The cache library of zentaopms.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Lu Fei <lufei@easycorp.ltd>
* @package cache
* @link http://www.zentao.net
*/
namespace ZenTao\Cache\Driver;
use ZenTao\Cache\SimpleCache\CacheInterface;
use ZenTao\Cache\SimpleCache\InvalidArgumentException;
class YacDriver implements CacheInterface
{
/**
* @var string
*/
private $namespace;
/**
* @var int
*/
private $defaultLifetime;
/**
* yac client
*
* @var \Yac
*/
protected $yac;
/**
* if your key is longer than this, maybe you can use md5 result as the key
*/
const KEY_MAX_LEN = 48;
public function __construct($namespace = '', $defaultLifetime = 0)
{
$this->namespace = $namespace;
$this->defaultLifetime = $defaultLifetime;
$this->yac = new \Yac($namespace);
}
public function get($key, $default = null)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
return $this->yac->get($key) ?: $default;
}
public function set($key, $value, $ttl = null)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
return $this->yac->set($key, $value, (int)$ttl);
}
public function delete($key)
{
$this->assertKeyName($key);
$key = $this->buildKeyName($key);
return $this->yac->delete($key);
}
public function clear()
{
return $this->yac->flush();
}
public function getMultiple($keys, $default = null)
{
if(!is_array($keys)) {
return array();
}
$hashKeyMap = array();
foreach($keys as $index => $key)
{
$this->assertKeyName($key);
if(strlen($key) > self::KEY_MAX_LEN)
{
$keys[$index] = $this->buildKeyName($key);
$hashKeyMap[$keys[$index]] = $key;
}
}
$results = $this->yac->get($keys);
if($results !== false)
{
foreach($results as $key => $value)
{
if(isset($hashKeyMap[$key]))
{
$results[$hashKeyMap[$key]] = $value;
unset($results[$key]);
}
}
return $results;
}
$results = array();
foreach($keys as $key)
{
$results[$key] = $default;
}
return $results;
}
public function setMultiple($values, $ttl = null)
{
if(!is_array($values)) return false;
foreach($values as $key => $value)
{
if(strlen($key) > self::KEY_MAX_LEN)
{
$values[$this->buildKeyName($key)] = $value;
unset($values[$key]);
}
}
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
return $this->yac->set($values, $ttl);
}
public function deleteMultiple($keys)
{
foreach($keys as $index => $key)
{
$keys[$index] = $this->buildKeyName($key);
}
return $this->yac->delete($keys);
}
public function has($key)
{
return $this->get($key) !== null;
}
/**
* @param string $key
*
* @return string
*/
private function buildKeyName($key)
{
if(strlen($key) > self::KEY_MAX_LEN)
{
$key = md5($key);
}
return $key;
}
/**
* @param string[] $keys
*
* @return string[]
*/
private function buildKeyNames(array $keys)
{
return array_map(function ($key) {
return $this->buildKeyName($key);
}, $keys);
}
/**
* @param mixed $key
*
* @throws InvalidArgumentException
*/
private function assertKeyName($key)
{
if(!is_scalar($key) || is_bool($key)) throw new InvalidArgumentException();
}
/**
* @param string[] $keys
*
* @throws InvalidArgumentException
*/
private function assertKeyNames(array $keys)
{
array_map(function ($value) {
$this->assertKeyName($value);
}, $keys);
}
}
+7
View File
@@ -0,0 +1,7 @@
<?php
namespace ZenTao\Cache\SimpleCache;
class CacheException extends \RuntimeException
{
}
+114
View File
@@ -0,0 +1,114 @@
<?php
namespace ZenTao\Cache\SimpleCache;
interface CacheInterface
{
/**
* Fetches a value from the cache.
*
* @param string $key The unique key of this item in the cache.
* @param mixed $default Default value to return if the key does not exist.
*
* @return mixed The value of the item from the cache, or $default in case of cache miss.
*
* @throws InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function get($key, $default = null);
/**
* Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
*
* @param string $key The key of the item to store.
* @param mixed $value The value of the item to store, must be serializable.
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*
* @throws InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function set($key, $value, $ttl = null);
/**
* Delete an item from the cache by its unique key.
*
* @param string $key The unique cache key of the item to delete.
*
* @return bool True if the item was successfully removed. False if there was an error.
*
* @throws InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function delete($key);
/**
* Wipes clean the entire cache's keys.
*
* @return bool True on success and false on failure.
*/
public function clear();
/**
* Obtains multiple cache items by their unique keys.
*
* @param iterable<string> $keys A list of keys that can be obtained in a single operation.
* @param mixed $default Default value to return for keys that do not exist.
*
* @return iterable<string, mixed> A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
*
* @throws InvalidArgumentException
* MUST be thrown if $keys is neither an array nor a Traversable,
* or if any of the $keys are not a legal value.
*/
public function getMultiple($keys, $default = null);
/**
* Persists a set of key => value pairs in the cache, with an optional TTL.
*
* @param iterable $values A list of key => value pairs for a multiple-set operation.
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
* the driver supports TTL then the library may set a default value
* for it or let the driver take care of that.
*
* @return bool True on success and false on failure.
*
* @throws InvalidArgumentException
* MUST be thrown if $values is neither an array nor a Traversable,
* or if any of the $values are not a legal value.
*/
public function setMultiple($values, $ttl = null);
/**
* Deletes multiple cache items in a single operation.
*
* @param iterable<string> $keys A list of string-based keys to be deleted.
*
* @return bool True if the items were successfully removed. False if there was an error.
*
* @throws InvalidArgumentException
* MUST be thrown if $keys is neither an array nor a Traversable,
* or if any of the $keys are not a legal value.
*/
public function deleteMultiple($keys);
/**
* Determines whether an item is present in the cache.
*
* NOTE: It is recommended that has() is only to be used for cache warming type purposes
* and not to be used within your live applications operations for get/set, as this method
* is subject to a race condition where your has() will return true and immediately after,
* another script can remove it making the state of your app out of date.
*
* @param string $key The cache item key.
*
* @return bool
*
* @throws InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function has($key);
}
+7
View File
@@ -0,0 +1,7 @@
<?php
namespace ZenTao\Cache\SimpleCache;
class InvalidArgumentException extends CacheException
{
}
+2 -4
View File
@@ -218,8 +218,8 @@ class Gitea
$path = ltrim($path, DIRECTORY_SEPARATOR);
$count = $count == 0 ? '' : "-n $count";
/* compatible with svn. */
if($fromRevision == 'HEAD' and $this->branch) $fromRevision = $this->branch;
if($toRevision == 'HEAD' and $this->branch) $toRevision = $this->branch;
if($fromRevision === 'HEAD' and $this->branch) $fromRevision = $this->branch;
if($toRevision === 'HEAD' and $this->branch) $toRevision = $this->branch;
if($fromRevision === $toRevision)
{
$logs = array();
@@ -748,14 +748,12 @@ class Gitea
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
$infos = array();
foreach($list as $entry)
{
list($mod, $kind, $revision, $size, $name) = preg_split('/[\t ]+/', $entry);
/* Get commit info. */
$pathName = ltrim($path . DIRECTORY_SEPARATOR . $name, DIRECTORY_SEPARATOR);
$info->kind = $kind == 'tree' ? 'dir' : 'file';
if($kind == 'tree')
{
$this->getAllFiles($pathName, $revision, $lists);
-2
View File
@@ -745,14 +745,12 @@ class GitRepo
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
$infos = array();
foreach($list as $entry)
{
list($mod, $kind, $revision, $size, $name) = preg_split('/[\t ]+/', $entry);
/* Get commit info. */
$pathName = ltrim($path . DIRECTORY_SEPARATOR . $name, DIRECTORY_SEPARATOR);
$info->kind = $kind == 'tree' ? 'dir' : 'file';
if($kind == 'tree')
{
$this->getAllFiles($pathName, $revision, $lists);
-2
View File
@@ -783,14 +783,12 @@ class Gogs
$list = execCmd($cmd . ' 2>&1', 'array', $result);
if($result) return array();
$infos = array();
foreach($list as $entry)
{
list($mod, $kind, $revision, $size, $name) = preg_split('/[\t ]+/', $entry);
/* Get commit info. */
$pathName = ltrim($path . DIRECTORY_SEPARATOR . $name, DIRECTORY_SEPARATOR);
$info->kind = $kind == 'tree' ? 'dir' : 'file';
if($kind == 'tree')
{
$this->getAllFiles($pathName, $revision, $lists);
+1 -1
View File
@@ -376,7 +376,7 @@ class action extends control
/* Check type of siblings. */
$siblings = $this->dao->select('DISTINCT type')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('parent')->eq($execution->parent)->fetchPairs('type');
if($execution->type == 'stage' and (isset($bsiblings['sprint']) or isset($siblings['kanban']))) die(js::alert($this->lang->action->hasOtherType[$execution->type]));
if($execution->type == 'stage' and (isset($siblings['sprint']) or isset($siblings['kanban']))) die(js::alert($this->lang->action->hasOtherType[$execution->type]));
if(($execution->type == 'sprint' or $execution->type == 'kanban') and isset($siblings['stage'])) die(js::alert($this->lang->action->hasOtherType[$execution->type]));
/* If parent stage is not exists, you should recover its parent stages, refresh status. */
+3 -1
View File
@@ -489,7 +489,7 @@ class actionModel extends model
elseif($actionName == 'importedcard')
{
$title = $this->dao->select('name')->from(TABLE_KANBAN)->where('id')->eq($action->extra)->fetch('name');
if($title) $action->extra = common::hasPriv('kanban', 'view') ? html::a(helper::createLink('kanban', 'view', "kanbanID=$action->extra"), "#$action->extra " . $title) : "#$action->extra " . $title;
if($title) $action->extra = (common::hasPriv('kanban', 'view') and !isonlybody()) ? html::a(helper::createLink('kanban', 'view', "kanbanID=$action->extra"), "#$action->extra " . $title) : "#$action->extra " . $title;
}
elseif($actionName == 'createchildren')
{
@@ -938,6 +938,8 @@ class actionModel extends model
}
else
{
if($actionType == 'restoredsnapshot' && in_array($action->objectType, array('vm', 'zanode')) && $value == 'defaultSnap') $value = $this->lang->$objectType->snapshot->defaultSnapName;
$desc = str_replace('$' . $key, $value, $desc);
}
}
+7 -7
View File
@@ -8,9 +8,9 @@ if(!isset($config->safe)) $config->safe = new stdclass();
if(!isset($config->safe->weak)) $config->safe->weak = '123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123';
$config->admin->menuGroup['system'] = array('custom|mode', 'backup', 'cron', 'action|trash', 'admin|xuanxuan', 'setting|xuanxuan', 'admin|license', 'admin|checkweak', 'admin|resetpwdsetting', 'admin|safe', 'custom|timezone', 'search|buildindex', 'admin|tableengine', 'ldap', 'custom|libreoffice', 'conference', 'client');
$config->admin->menuGroup['user'] = array('dept', 'company', 'user', 'group');
$config->admin->menuGroup['company'] = array('dept', 'company', 'user', 'group', 'tutorial');
$config->admin->menuGroup['switch'] = array('admin|setmodule');
$config->admin->menuGroup['model'] = array('auditcl', 'stage', 'design', 'cmcl', 'reviewcl', 'custom|required', 'custom|set', 'custom|flow', 'custom|code', 'custom|estimate', 'custom|hours', 'subject', 'process', 'activity', 'zoutput', 'classify', 'holiday', 'reviewsetting');
$config->admin->menuGroup['model'] = array('auditcl', 'stage', 'design', 'cmcl', 'reviewcl', 'custom|required', 'custom|set', 'custom|flow', 'custom|code', 'custom|percent','custom|estimate', 'custom|hours', 'subject', 'process', 'activity', 'zoutput', 'classify', 'holiday', 'reviewsetting');
$config->admin->menuGroup['feature'] = array('custom|set', 'custom|product', 'custom|execution', 'custom|required', 'custom|kanban', 'approvalflow', 'measurement', 'meetingroom', 'custom|browsestoryconcept', 'custom|kanban', 'sqlbuilder', 'report');
$config->admin->menuGroup['template'] = array('custom|set', 'baseline');
$config->admin->menuGroup['message'] = array('mail', 'webhook', 'sms', 'message');
@@ -72,14 +72,14 @@ $config->admin->extAPIURL = $config->admin->apiSite . 'extension-apiGetExte
$config->admin->patchAPIURL = $config->admin->apiSite . 'extension-apiGetExtensions-bymodule-MTIxOA==-0-100-1.json';
$config->admin->downloadAPIURL = $config->admin->apiSite . 'download.json';
$config->admin->videoAPIURL = $config->admin->apiSite . 'publicclass.json';
$config->admin->liteMenuList = array('system', 'user', 'feature', 'message', 'extension', 'dev');
$config->admin->liteMenuList = array('system', 'company', 'feature', 'message', 'extension', 'dev');
$config->admin->helpURL['system'] = 'https://www.zentao.net/book/zentaopms/538.html';
$config->admin->helpURL['user'] = 'https://www.zentao.net/book/zentaopms/538.html';
$config->admin->helpURL['switch'] = 'https://www.zentao.net/book/zentaopms/538.html';
$config->admin->helpURL['company'] = 'https://www.zentao.net/book/zentaopms/38.html';
$config->admin->helpURL['switch'] = 'https://www.zentao.net/book/zentaopms/38.html';
$config->admin->helpURL['model'] = 'https://www.zentao.net/book/zentaopms/533.html';
$config->admin->helpURL['feature'] = 'https://www.zentao.net/book/zentaopms/538.html';
$config->admin->helpURL['template'] = 'https://www.zentao.net/book/zentaopms/538.html';
$config->admin->helpURL['feature'] = 'https://www.zentao.net/book/zentaopms/38.html';
$config->admin->helpURL['template'] = 'https://www.zentao.net/book/zentaopms/38.html';
$config->admin->helpURL['message'] = 'https://www.zentao.net/book/zentaopms/email-notification-541.html';
$config->admin->helpURL['extension'] = 'https://www.zentao.net/book/zentaopms/536.html';
$config->admin->helpURL['dev'] = 'https://www.zentao.net/book/zentaopms/537.html';
+56 -8
View File
@@ -11,6 +11,25 @@
*/
class admin extends control
{
/**
* The gogs constructor.
* @param string $moduleName
* @param string $methodName
*/
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
if(!isset($this->config->global->sn))
{
$this->loadModel('setting');
$this->setting->setItem('system.common.global.sn', $this->setting->computeSN());
if(!isset($this->config->global)) $this->config->global = new stdclass();
$this->config->global->sn = $this->setting->getItem('owner=system&module=common&section=global&key=sn');
}
}
/**
* Index page.
* @access public
@@ -34,23 +53,52 @@ class admin extends control
$this->loadModel('misc');
$hasInternet = $this->admin->checkInternet();
$clientLang = $this->app->getClientLang();
$langNotCN = common::checkNotCN();
$dateUsed = $this->admin->genDateUsed();
$clientLang = $this->app->getClientLang();
$langNotCN = common::checkNotCN();
$dateUsed = $this->admin->genDateUsed();
$zentaoData = $this->admin->getZentaoData();
$hasInternet = $zentaoData->hasData;
$this->view->title = $this->lang->admin->common;
$this->view->position[] = $this->lang->admin->index;
$this->view->plugins = $this->admin->getExtensionsByAPI('plugin', $langNotCN ? 5 : 6, $hasInternet);
$this->view->patches = $this->admin->getExtensionsByAPI('patch', 5, $hasInternet);
$this->view->plugins = $zentaoData->plugins;
$this->view->patches = $zentaoData->patches;
$this->view->dateUsed = $dateUsed;
$this->view->hasInternet = $hasInternet;
$this->view->dynamics = ($hasInternet and !$langNotCN) ? $this->admin->getDynamicsByAPI(3) : array();
$this->view->publicClass = ($hasInternet and !$langNotCN) ? $this->admin->getPublicClassByAPI(3) : array();
$this->view->dynamics = $zentaoData->news;
$this->view->publicClass = $zentaoData->publicclass;
$this->view->langNotCN = $langNotCN;
$this->display();
}
/**
* Get zentao.net data by api.
*
* @access public
* @return void
*/
public function ajaxSetZentaoData()
{
$hasInternet = $this->admin->checkInternet();
if($hasInternet)
{
$nextWeek = date('Y-m-d', strtotime('-7 days'));
$zentaoData = $this->loadModel('block')->getZentaoData($nextWeek);
if(empty($zentaoData))
{
$this->admin->setExtensionsByAPI('plugin', 6);
$this->admin->setExtensionsByAPI('patch', 5);
$this->admin->setDynamicsByAPI(3);
$this->admin->setPublicClassByAPI(3);
}
}
return $this->send(array('result' => 'success'));
}
/**
* Ignore notice of register and bind.
*
+16 -6
View File
@@ -20,6 +20,8 @@
.font-20 {font-size: 20px;}
.font-24 {font-size: 24px;}
.radius-4 {border-radius: 4px;}
.white-nowrap {white-space: nowrap;}
.w-full {width: 100%;}
#notice {margin: -20px -20px 20px; padding: 20px;}
#zentaoLinks {margin-top: 20px;}
@@ -39,9 +41,13 @@
.settings-list > .setting-box > button.btn {padding: 5px 10px; height: 100%; width: 100%; display: flex; flex-direction: column; justify-content: space-between; cursor: pointer; white-space: unset; text-align: unset; border: 1px solid rgba(227, 228, 233, 0.6)}
.settings-list > .setting-box > .btn:hover {background: unset;}
.settings-list > .setting-box > .btn[disabled] {cursor: not-allowed; pointer-events: unset;}
.settings-list > .setting-box > .btn[disabled] > a {pointer-events: none;}
.settings-list > .setting-box > .btn[disabled] > a,
.settings-list > .setting-box > .btn[disabled] a.setting-help,
.settings-list > .setting-box > .btn[disabled] p.setting-desc {pointer-events: none;}
.settings-list > .setting-box > .btn > h4 {padding-right: 5px;}
.settings-list > .setting-box > .btn > h4 > div {gap: 3px;}
.settings-list > .setting-box > .btn > h4 > img {padding-right: 8px; padding-bottom: 3px; width: 32px; height: 27px;}
.settings-list > .setting-box > .btn > .setting-desc {padding-bottom: 16px; color: #5E626D; line-height: 25px; height: 50px;}
.settings-list > .setting-box > .btn > .setting-desc {padding-bottom: 16px; line-height: 25px; height: 50px; overflow: hidden;}
.settings-list.lite-setting > .setting-box {flex: 1 1 30%;}
.plugin-list {display: flex; flex-wrap: wrap; padding: 12px 4px 4px 4px;}
@@ -56,10 +62,12 @@
.official {justify-content: center;}
.official > .panel-title {position: absolute; top: 0px;}
.official-img {background-image: url('/static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;}
.official-content {flex: 0 0 60%; display: flex; flex-direction: column; justify-content: center; padding-left: 10px;}
.official-img {background-image: url('static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;}
.official-content {flex: 0 0 60%; display: flex; flex-direction: column; padding-left: 10px; padding-top: 15px;}
.official-content > .content {color: #838A9D; font-size: 12px; line-height: 22px; padding-top: 6px;}
.official-content > .title {color: #313C52; font-size: 13px; line-height: 14px;}
.panel-link {color: #313c52; padding-left: 10px; font-size: 13px;}
.panel-link > a {border-bottom: 1px solid;}
.classList > .classItem {flex: 1 1 30%; margin: 5px 5px 16px 5px; border: 1px solid rgba(227, 228, 233, 0.6); border-radius: 4px; padding-bottom: 5px; align-items: center;}
.classItem > .imgBack {flex: 1 1 50%;}
@@ -69,13 +77,15 @@
.panel.publicClass {padding: 0 10px;}
.icon.follow-us {font-size: 20px; padding-left: 10px;}
.setting-help {width: 45px; color: #9EA3B0; padding-top: 15px;}
.setting-help {color: #9EA3B0; padding-left: 5px;}
.setting-help > a {font-size: 15px;}
[lang^='zh'] .setting-help {padding-top: 0;}
.pointer-none {pointer-events: none;}
/* css for without internet */
.main.without-internet {display: flex; flex-wrap: wrap;}
.main.without-internet > .plug.panel {flex: 1 1 60%; margin-bottom: unset; margin-right: 16px;}
.main.without-internet > .bottom {flex: 1 1 30%;}
.main.without-internet > .bottom > .official.panel {margin-right: unset;}
.main.without-internet > .bottom > .official.panel > .main-panel {flex-direction: row-reverse;}
@@ -84,7 +94,7 @@
.time-block {background: #EDEEF2; padding:2px 4px; border-radius: 4px; color: #0B0F18; font-size: 15px; margin: 0 4px;}
.dynamic-block {height: 74px; padding: 12px 16px; display: flex; justify-content: space-between; position: relative; line-height: 20px; border-top: 1px solid #E3E4E9;}
.dynamic-content {height: 50px; line-height: 25px; overflow: hidden;}
.dynamic-time {white-space: nowrap; position: absolute; right: 12px; bottom: 10px; padding-right: 12px; background: white; color: #5E626D;}
.dynamic-time {white-space: nowrap; position: absolute; right: 12px; bottom: 12px; padding-left: 10px; padding-right: 12px; background: white; color: #5E626D;}
.time-count {letter-spacing: 1px;}
.patch-block {padding: 10px 16px 12px; line-height: 20px; border-top: 1px solid #E3E4E9;}
+2
View File
@@ -10,4 +10,6 @@ $(function()
{
window.open($(this).data('link'));
});
if(!hasInternet) $.get(createLink('admin', 'ajaxSetZentaoData'));
});
+8 -4
View File
@@ -66,12 +66,13 @@ $lang->admin->notice->ignore = "Ignorieren";
$lang->admin->notice->int = "『%s』sollte eine positive Zahl sein.";
$lang->admin->registerNotice = new stdclass();
$lang->admin->registerNotice->common = 'Verbinde neues Konto';
$lang->admin->registerNotice->common = 'Register Account';
$lang->admin->registerNotice->caption = 'In der Zentao Community registieren';
$lang->admin->registerNotice->click = 'Bitte registieren Sie sich hier';
$lang->admin->registerNotice->lblAccount = 'mindestens 3 Zeichen bitte; mit Buchsten und Ziffern.';
$lang->admin->registerNotice->lblPasswd = 'mindestens 6 Zeichen bitte; mit Buchsten und Ziffern.';
$lang->admin->registerNotice->submit = 'Registieren';
$lang->admin->registerNotice->submitHere = 'RegistierenHere';
$lang->admin->registerNotice->bind = "Verbinde bestehendes Konto";
$lang->admin->registerNotice->success = "Sie haben sich erfolgreich registriert!";
@@ -86,9 +87,11 @@ $lang->admin->setModule->opened = 'Opened';
$lang->admin->setModule->closed = 'Closed';
$lang->admin->setModule->my = 'My';
$lang->admin->setModule->product = 'Product';
$lang->admin->setModule->scrum = 'Scrum Project';
$lang->admin->setModule->waterfall = 'Waterfall Project';
$lang->admin->setModule->product = $lang->productCommon;
$lang->admin->setModule->scrum = 'Scrum ' . $lang->projectCommon;
$lang->admin->setModule->waterfall = 'Waterfall ' . $lang->projectCommon;
$lang->admin->setModule->agileplus = 'Agile + ' . $lang->projectCommon;
$lang->admin->setModule->waterfallplus = 'Waterfall + ' . $lang->projectCommon;
$lang->admin->setModule->assetlib = 'Assetlib';
$lang->admin->setModule->other = 'Other';
@@ -183,6 +186,7 @@ $lang->admin->updateDynamics = 'Dynamics';
$lang->admin->updatePatch = 'Patch';
$lang->admin->upgradeRecommend = 'Recommend Upgrade';
$lang->admin->zentaoUsed = 'You have used ZenTao';
$lang->admin->noPriv = 'You have no permission to visit this block.';
$lang->admin->openTag = 'ZenTao Opensource ';
$lang->admin->bizTag = 'ZenTao Biz ';
+8 -4
View File
@@ -66,12 +66,13 @@ $lang->admin->notice->ignore = "Ignore";
$lang->admin->notice->int = "『%s』should be a positive integer.";
$lang->admin->registerNotice = new stdclass();
$lang->admin->registerNotice->common = 'Bind Account';
$lang->admin->registerNotice->common = 'Register Account';
$lang->admin->registerNotice->caption = 'ZenTao Community Signup';
$lang->admin->registerNotice->click = 'Sign Up';
$lang->admin->registerNotice->lblAccount = '>= 3 letters and numbers';
$lang->admin->registerNotice->lblPasswd = '>= 6 letters and numbers';
$lang->admin->registerNotice->submit = 'Submit';
$lang->admin->registerNotice->submitHere = 'RegistierenHere';
$lang->admin->registerNotice->bind = "Bind Exsiting Account";
$lang->admin->registerNotice->success = "You have signed up!";
@@ -86,9 +87,11 @@ $lang->admin->setModule->opened = 'Opened';
$lang->admin->setModule->closed = 'Closed';
$lang->admin->setModule->my = 'My';
$lang->admin->setModule->product = 'Product';
$lang->admin->setModule->scrum = 'Scrum Project';
$lang->admin->setModule->waterfall = 'Waterfall Project';
$lang->admin->setModule->product = $lang->productCommon;
$lang->admin->setModule->scrum = 'Scrum ' . $lang->projectCommon;
$lang->admin->setModule->waterfall = 'Waterfall ' . $lang->projectCommon;
$lang->admin->setModule->agileplus = 'Agile + ' . $lang->projectCommon;
$lang->admin->setModule->waterfallplus = 'Waterfall + ' . $lang->projectCommon;
$lang->admin->setModule->assetlib = 'Assetlib';
$lang->admin->setModule->other = 'Other';
@@ -183,6 +186,7 @@ $lang->admin->updateDynamics = 'Dynamics';
$lang->admin->updatePatch = 'Patch';
$lang->admin->upgradeRecommend = 'Recommend Upgrade';
$lang->admin->zentaoUsed = 'You have used ZenTao';
$lang->admin->noPriv = 'You have no permission to visit this block.';
$lang->admin->openTag = 'ZenTao Opensource ';
$lang->admin->bizTag = 'ZenTao Biz ';
+8 -4
View File
@@ -66,12 +66,13 @@ $lang->admin->notice->ignore = "Ignorer";
$lang->admin->notice->int = "『 %s 』 devrait être un entier positif.";
$lang->admin->registerNotice = new stdclass();
$lang->admin->registerNotice->common = 'Connectez-vous avec votre nouveau compte';
$lang->admin->registerNotice->common = 'Register Account';
$lang->admin->registerNotice->caption = "S'enregistrer sur la communauté Zentao";
$lang->admin->registerNotice->click = "S'enregistrer ici";
$lang->admin->registerNotice->lblAccount = '>= 3 lettres et chiffres';
$lang->admin->registerNotice->lblPasswd = '>= 6 lettres et chiffres';
$lang->admin->registerNotice->submit = "S'enregistrer";
$lang->admin->registerNotice->submitHere = "S'enregistrer here";
$lang->admin->registerNotice->bind = "S'associer à un compte existant";
$lang->admin->registerNotice->success = "Vous êtes enregistré !";
@@ -86,9 +87,11 @@ $lang->admin->setModule->opened = 'Opened';
$lang->admin->setModule->closed = 'Closed';
$lang->admin->setModule->my = 'My';
$lang->admin->setModule->product = 'Product';
$lang->admin->setModule->scrum = 'Scrum Project';
$lang->admin->setModule->waterfall = 'Waterfall Project';
$lang->admin->setModule->product = $lang->productCommon;
$lang->admin->setModule->scrum = 'Scrum ' . $lang->projectCommon;
$lang->admin->setModule->waterfall = 'Waterfall ' . $lang->projectCommon;
$lang->admin->setModule->agileplus = 'Agile + ' . $lang->projectCommon;
$lang->admin->setModule->waterfallplus = 'Waterfall + ' . $lang->projectCommon;
$lang->admin->setModule->assetlib = 'Assetlib';
$lang->admin->setModule->other = 'Other';
@@ -183,6 +186,7 @@ $lang->admin->updateDynamics = 'Dynamics';
$lang->admin->updatePatch = 'Patch';
$lang->admin->upgradeRecommend = 'Recommend Upgrade';
$lang->admin->zentaoUsed = 'You have used ZenTao';
$lang->admin->noPriv = 'You have no permission to visit this block.';
$lang->admin->openTag = 'ZenTao Opensource ';
$lang->admin->bizTag = 'ZenTao Biz ';
+67 -42
View File
@@ -3,45 +3,46 @@ global $config;
$lang->admin->menuList = new stdclass();
$lang->admin->menuList->system['name'] = $lang->admin->menuSetting['system']['name'];
$lang->admin->menuList->system['desc'] = $lang->admin->menuSetting['system']['desc'];
$lang->admin->menuList->system['order'] = 1;
$lang->admin->menuList->user['name'] = $lang->admin->menuSetting['user']['name'];
$lang->admin->menuList->user['desc'] = $lang->admin->menuSetting['user']['desc'];
$lang->admin->menuList->user['order'] = 2;
$lang->admin->menuList->system['order'] = 5;
$lang->admin->menuList->switch['name'] = $lang->admin->menuSetting['switch']['name'];
$lang->admin->menuList->switch['desc'] = $lang->admin->menuSetting['switch']['desc'];
$lang->admin->menuList->switch['order'] = 3;
$lang->admin->menuList->switch['link'] = 'admin|setmodule';
$lang->admin->menuList->switch['order'] = 10;
$lang->admin->menuList->company['name'] = $lang->admin->menuSetting['user']['name'];
$lang->admin->menuList->company['desc'] = $lang->admin->menuSetting['user']['desc'];
$lang->admin->menuList->company['order'] = 15;
$lang->admin->menuList->model['name'] = $lang->admin->menuSetting['model']['name'];
$lang->admin->menuList->model['desc'] = $lang->admin->menuSetting['model']['desc'];
$lang->admin->menuList->model['order'] = 4;
$lang->admin->menuList->model['order'] = 20;
$lang->admin->menuList->feature['name'] = $lang->admin->menuSetting['feature']['name'];
$lang->admin->menuList->feature['desc'] = $lang->admin->menuSetting['feature']['desc'];
$lang->admin->menuList->feature['order'] = 5;
$lang->admin->menuList->feature['order'] = 25;
$lang->admin->menuList->template['name'] = $lang->admin->menuSetting['template']['name'];
$lang->admin->menuList->template['desc'] = $lang->admin->menuSetting['template']['desc'];
$lang->admin->menuList->template['order'] = 6;
$lang->admin->menuList->template['order'] = 30;
$lang->admin->menuList->message['name'] = $lang->admin->menuSetting['message']['name'];
$lang->admin->menuList->message['desc'] = $lang->admin->menuSetting['message']['desc'];
$lang->admin->menuList->message['order'] = 7;
$lang->admin->menuList->message['order'] = 35;
$lang->admin->menuList->extension['name'] = $lang->admin->menuSetting['extension']['name'];
$lang->admin->menuList->extension['desc'] = $lang->admin->menuSetting['extension']['desc'];
$lang->admin->menuList->extension['link'] = 'extension|browse';
$lang->admin->menuList->extension['order'] = 8;
$lang->admin->menuList->extension['order'] = 40;
$lang->admin->menuList->dev['name'] = $lang->admin->menuSetting['dev']['name'];
$lang->admin->menuList->dev['desc'] = $lang->admin->menuSetting['dev']['desc'];
$lang->admin->menuList->dev['order'] = 9;
$lang->admin->menuList->dev['order'] = 45;
$lang->admin->menuList->convert['name'] = $lang->admin->menuSetting['convert']['name'];
$lang->admin->menuList->convert['desc'] = $lang->admin->menuSetting['convert']['desc'];
$lang->admin->menuList->convert['link'] = 'convert|convertjira';
$lang->admin->menuList->convert['order'] = 10;
$lang->admin->menuList->convert['order'] = 50;
$lang->admin->menuList->system['subMenu']['mode'] = array('link' => "{$lang->custom->mode}|custom|mode|");
$lang->admin->menuList->system['subMenu']['backup'] = array('link' => "{$lang->backup->common}|backup|index|");
@@ -63,38 +64,45 @@ $lang->admin->menuList->system['menuOrder']['50'] = 'tableengine';
$lang->admin->menuList->system['dividerMenu'] = ',safe,';
$lang->admin->menuList->user['subMenu']['dept'] = array('link' => "{$lang->dept->common}|dept|browse|", 'subModule' => 'dept');
$lang->admin->menuList->user['subMenu']['user'] = array('link' => "{$lang->user->common}|company|browse|", 'subModule' => 'user');
$lang->admin->menuList->user['subMenu']['group'] = array('link' => "{$lang->priv}|group|browse|", 'subModule' => 'group');
$lang->admin->menuList->company['subMenu']['dept'] = array('link' => "{$lang->dept->common}|dept|browse|", 'subModule' => 'dept');
$lang->admin->menuList->company['subMenu']['browseUser'] = array('link' => "{$lang->user->common}|company|browse|", 'subModule' => 'user,tutorial');
$lang->admin->menuList->company['subMenu']['group'] = array('link' => "{$lang->priv}|group|browse|", 'subModule' => 'group');
$lang->admin->menuList->user['menuOrder']['5'] = 'dept';
$lang->admin->menuList->user['menuOrder']['10'] = 'user';
$lang->admin->menuList->user['menuOrder']['15'] = 'group';
$lang->admin->menuList->company['menuOrder']['5'] = 'dept';
$lang->admin->menuList->company['menuOrder']['10'] = 'browseUser';
$lang->admin->menuList->company['menuOrder']['15'] = 'group';
$lang->admin->menuList->switch['subMenu']['setmodule'] = array('link' => "{$lang->admin->module}|admin|setmodule|");
$lang->admin->menuList->switch['menuOrder']['5'] = 'setmodule';
$lang->admin->menuList->model['subMenu']['common'] = array('link' => "{$lang->globalSetting}|custom|required|module=project", 'subModule' => 'custom,subject,holiday');
$lang->admin->menuList->model['subMenu']['scrum'] = array('link' => "{$lang->scrumModel}|auditcl|scrumbrowse|", 'subModule' => 'auditcl');
$lang->admin->menuList->model['subMenu']['waterfall'] = array('link' => "{$lang->waterfallModel}|stage|settype|", 'subModule' => 'stage');
$lang->admin->menuList->model['subMenu']['common'] = array('link' => "{$lang->globalSetting}|custom|required|module=project", 'subModule' => 'custom,subject,holiday,stage', 'exclude' => 'stage-browse,stage-plusbrowse,stage-create,stage-edit,stage-batchcreate');
$lang->admin->menuList->model['subMenu']['scrum'] = array('link' => "{$lang->scrumModel}|auditcl|scrumbrowse|", 'subModule' => 'auditcl');
$lang->admin->menuList->model['subMenu']['waterfall'] = array('link' => "{$lang->waterfallModel}|stage|browse|", 'subModule' => 'stage', 'exclude' => 'stage-settype,stage-plusbrowse');
$lang->admin->menuList->model['subMenu']['agileplus'] = array('link' => "{$lang->agilePlusModel}|auditcl|agileplusbrowse|", 'subModule' => 'auditcl');
$lang->admin->menuList->model['subMenu']['waterfallplus'] = array('link' => "{$lang->waterfallPlusModel}|stage|plusbrowse|", 'subModule' => 'stage', 'exclude' => 'stage-settype,stage-browse');
$lang->admin->menuList->model['menuOrder']['5'] = 'common';
$lang->admin->menuList->model['menuOrder']['10'] = 'scrum';
$lang->admin->menuList->model['menuOrder']['15'] = 'waterfall';
$lang->admin->menuList->model['menuOrder']['20'] = 'agileplus';
$lang->admin->menuList->model['menuOrder']['25'] = 'waterfallplus';
$lang->admin->menuList->model['tabMenu']['common']['project'] = array('link' => "{$lang->project->common}|custom|required|module=project", 'alias' => 'set', 'exclude' => 'custom', 'links' => array('custom|set|'));
$lang->admin->menuList->model['tabMenu']['common']['build'] = array('link' => "{$lang->build->common}|custom|required|module=build", 'alias' => 'set', 'exclude' => 'custom');
$lang->admin->menuList->model['tabMenu']['common']['flow'] = array('link' => "{$lang->custom->flow}|custom|flow|", 'divider' => true);
$lang->admin->menuList->model['tabMenu']['common']['code'] = array('link' => "{$lang->code}|custom|code|");
$lang->admin->menuList->model['tabMenu']['common']['hours'] = array('link' => "{$lang->workingHour}|custom|hours|", 'subModule' => 'holiday', 'links' => array('holiday|browse|'));
$lang->admin->menuList->model['tabMenu']['waterfall']['stage'] = array('link' => "{$lang->stage->common}|stage|settype|", 'subModule' => 'stage', 'links' => array('stage|browse|'));
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['5'] = 'project';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['10'] = 'build';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['35'] = 'flow';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['40'] = 'code';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['45'] = 'hours';
$lang->admin->menuList->model['tabMenu']['menuOrder']['waterfall']['5'] = 'stage';
$lang->admin->menuList->model['tabMenu']['common']['project'] = array('link' => "{$lang->project->common}|custom|required|module=project", 'alias' => 'set', 'exclude' => 'custom', 'links' => array('custom|set|module=project&field=unitList'));
if(helper::hasFeature('waterfall') or helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['common']['stage'] = array('link' => "{$lang->stage->type}|stage|settype|", 'subModule' => 'stage');
$lang->admin->menuList->model['tabMenu']['common']['build'] = array('link' => "{$lang->build->common}|custom|required|module=build", 'alias' => 'set', 'exclude' => 'custom');
$lang->admin->menuList->model['tabMenu']['common']['flow'] = array('link' => "{$lang->custom->flow}|custom|flow|", 'divider' => true);
$lang->admin->menuList->model['tabMenu']['common']['code'] = array('link' => "{$lang->code}|custom|code|");
$lang->admin->menuList->model['tabMenu']['common']['percent'] = array('link' => "{$lang->stage->percent}|custom|percent|");
$lang->admin->menuList->model['tabMenu']['common']['hours'] = array('link' => "{$lang->workingHour}|custom|hours|", 'subModule' => 'holiday', 'links' => array('holiday|browse|', 'custom|hours|'));
if(helper::hasFeature('waterfall')) $lang->admin->menuList->model['tabMenu']['waterfall']['stage'] = array('link' => "{$lang->stage->list}|stage|browse|", 'subModule' => 'stage', 'exclude' => 'stage-plusbrowse');
if(helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['waterfallplus']['stage'] = array('link' => "{$lang->stage->list}|stage|plusbrowse|", 'subModule' => 'stage', 'exclude' => 'stage-browse');
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['5'] = 'project';
if(helper::hasFeature('waterfall') or helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['menuOrder']['common']['7'] = 'stage';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['10'] = 'build';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['35'] = 'flow';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['40'] = 'code';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['43'] = 'percent';
$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['45'] = 'hours';
if(helper::hasFeature('waterfall')) $lang->admin->menuList->model['tabMenu']['menuOrder']['waterfall']['5'] = 'stage';
if(helper::hasFeature('waterfallplus')) $lang->admin->menuList->model['tabMenu']['menuOrder']['waterfallplus']['5'] = 'stage';
$lang->admin->menuList->feature['subMenu']['my'] = array('link' => "{$lang->my->common}|custom|set|module=todo&field=priList", 'exclude' => 'set,required');
$lang->admin->menuList->feature['subMenu']['product'] = array('link' => "{$lang->productCommon}|custom|required|module=product", 'exclude' => 'set,required', 'alias' => 'browsestoryconcept,product');
@@ -157,7 +165,7 @@ $lang->admin->menuList->message['menuOrder']['10'] = 'webhook';
$lang->admin->menuList->message['menuOrder']['20'] = 'browser';
$lang->admin->menuList->message['menuOrder']['25'] = 'setting';
$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "API|dev|api|module=index");
$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "{$lang->api->doc}|dev|api|module=index");
$lang->admin->menuList->dev['subMenu']['db'] = array('link' => "{$lang->database}|dev|db|table=" . trim(TABLE_EFFORT, '`'));
$lang->admin->menuList->dev['subMenu']['editor'] = array('link' => "{$lang->editor}|dev|editor|");
$lang->admin->menuList->dev['subMenu']['entry'] = array('link' => "{$lang->admin->entry}|entry|browse|", 'subModule' => 'entry');
@@ -167,15 +175,28 @@ $lang->admin->menuList->dev['menuOrder']['10'] = 'db';
$lang->admin->menuList->dev['menuOrder']['15'] = 'editor';
$lang->admin->menuList->dev['menuOrder']['20'] = 'entry';
if($config->edition != 'max') unset($lang->admin->menuList->model['subMenu']['scrum'], $lang->admin->menuList->model['menuOrder']['10'], $lang->admin->menuList->template);
if($config->edition != 'max')
{
unset($lang->admin->menuList->model['subMenu']['scrum']);
unset($lang->admin->menuList->model['subMenu']['agileplus']);
unset($lang->admin->menuList->model['menuOrder']['10']);
unset($lang->admin->menuList->model['menuOrder']['20']);
unset($lang->admin->menuList->template);
}
if(!helper::hasFeature('waterfall'))
{
unset($lang->admin->menuList->model['subMenu']['waterfall']);
unset($lang->admin->menuList->model['menuOrder']['15']);
}
if($config->edition == 'max' and !helper::hasFeature('scrum_auditplan'))
if(!helper::hasFeature('waterfallplus'))
{
if(!helper::hasFeature('scrum_process')) unset($lang->admin->menuList->model['subMenu']['scrum'], $lang->admin->menuList->model['menuOrder']['10']);
unset($lang->admin->menuList->model['subMenu']['waterfallplus']);
unset($lang->admin->menuList->model['menuOrder']['25']);
}
if($config->edition == 'max')
{
if(!helper::hasFeature('scrum_auditplan') and !helper::hasFeature('scrum_process')) unset($lang->admin->menuList->model['subMenu']['scrum'], $lang->admin->menuList->model['menuOrder']['10']);
if(!helper::hasFeature('agileplus_auditplan') and !helper::hasFeature('agileplus_process')) unset($lang->admin->menuList->model['subMenu']['agileplus'], $lang->admin->menuList->model['menuOrder']['20']);
}
if($config->vision == 'lite')
@@ -189,8 +210,12 @@ if($config->vision == 'lite')
unset($lang->admin->menuList->model['subMenu']['scrum']);
unset($lang->admin->menuList->model['subMenu']['waterfall']);
unset($lang->admin->menuList->model['subMenu']['agileplus']);
unset($lang->admin->menuList->model['subMenu']['waterfallplus']);
unset($lang->admin->menuList->model['menuOrder']['10']);
unset($lang->admin->menuList->model['menuOrder']['15']);
unset($lang->admin->menuList->model['menuOrder']['20']);
unset($lang->admin->menuList->model['menuOrder']['25']);
unset($lang->admin->menuList->feature['subMenu']['product']);
unset($lang->admin->menuList->feature['subMenu']['execution']);
+1
View File
@@ -52,6 +52,7 @@ $lang->admin->registerNotice->click = 'Đăng ký';
$lang->admin->registerNotice->lblAccount = '>= 3 chữ và số';
$lang->admin->registerNotice->lblPasswd = '>= 6 chữ và số';
$lang->admin->registerNotice->submit = 'Gửi';
$lang->admin->registerNotice->submitHere = 'submitHere';
$lang->admin->registerNotice->bind = "Kết nối với tài khoản đang tồn tại";
$lang->admin->registerNotice->success = "Bạn đã đăng ký!";
+9 -5
View File
@@ -61,17 +61,18 @@ $lang->admin->info->account = "您的禅道社区账户为%s。";
$lang->admin->info->log = '超出存天数的日志会被删除,需要开启计划任务。';
$lang->admin->notice = new stdclass();
$lang->admin->notice->register = "友情提示:您还未在禅道社区(www.zentao.net)登记,%s进行登记,以及时获得禅道最新信息。";
$lang->admin->notice->register = "可%s禅道社区 www.zentao.net及时获得禅道最新信息。";
$lang->admin->notice->ignore = "不再提示";
$lang->admin->notice->int = "『%s』应当是正整数。";
$lang->admin->registerNotice = new stdclass();
$lang->admin->registerNotice->common = '注册新帐号绑定';
$lang->admin->registerNotice->common = '注册新帐号';
$lang->admin->registerNotice->caption = '禅道社区登记';
$lang->admin->registerNotice->click = '点击此处';
$lang->admin->registerNotice->lblAccount = '请设置您的用户名,英文字母和数字的组合,三位以上。';
$lang->admin->registerNotice->lblPasswd = '请设置您的密码。数字和字母的组合,六位以上。';
$lang->admin->registerNotice->submit = '登记';
$lang->admin->registerNotice->submitHere = '在此登记';
$lang->admin->registerNotice->bind = "绑定已有帐号";
$lang->admin->registerNotice->success = "登记账户成功";
@@ -86,9 +87,11 @@ $lang->admin->setModule->opened = '已开启';
$lang->admin->setModule->closed = '已关闭';
$lang->admin->setModule->my = '地盘';
$lang->admin->setModule->product = '产品';
$lang->admin->setModule->scrum = '敏捷项目';
$lang->admin->setModule->waterfall = '瀑布项目';
$lang->admin->setModule->product = $lang->productCommon;
$lang->admin->setModule->scrum = '敏捷' . $lang->projectCommon;
$lang->admin->setModule->waterfall = '瀑布' . $lang->projectCommon;
$lang->admin->setModule->agileplus = '融合敏捷' . $lang->projectCommon;
$lang->admin->setModule->waterfallplus = '融合瀑布' . $lang->projectCommon;
$lang->admin->setModule->assetlib = '资产库';
$lang->admin->setModule->other = '通用功能';
@@ -183,6 +186,7 @@ $lang->admin->updateDynamics = '更新动态';
$lang->admin->updatePatch = '补丁更新';
$lang->admin->upgradeRecommend = '推荐升级';
$lang->admin->zentaoUsed = '您已使用禅道';
$lang->admin->noPriv = '您没有访问该区块的权限。';
$lang->admin->openTag = '禅道';
$lang->admin->bizTag = '禅道企业版';
+99 -61
View File
@@ -269,13 +269,13 @@ class adminModel extends model
$this->setSwitcher($menuKey);
if(isset($this->lang->admin->menuList->$menuKey))
{
if(isset($this->lang->admin->menuList->$menuKey['subMenu']))
if(isset($this->lang->admin->menuList->{$menuKey}['subMenu']))
{
$moduleName = $this->app->rawModule;
$methodName = $this->app->rawMethod;
$firstParam = $this->app->rawParams ? reset($this->app->rawParams) : '';
foreach($this->lang->admin->menuList->$menuKey['subMenu'] as $subMenuKey => $subMenu)
foreach($this->lang->admin->menuList->{$menuKey}['subMenu'] as $subMenuKey => $subMenu)
{
$subModule = '';
if($moduleName == 'custom' and strpos(',required,set,', $methodName) !== false)
@@ -285,25 +285,25 @@ class adminModel extends model
}
if(!empty($subModule)) $subMenu['subModule'] = $subModule;
if(isset($this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey]))
if(isset($this->lang->admin->menuList->{$menuKey}['tabMenu'][$subMenuKey]))
{
if(!empty($subModule))
{
$this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey][$firstParam]['subModule'] = $subModule;
unset($this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey][$firstParam]['exclude']);
$this->lang->admin->menuList->{$menuKey}['tabMenu'][$subMenuKey][$firstParam]['subModule'] = $subModule;
unset($this->lang->admin->menuList->{$menuKey}['tabMenu'][$subMenuKey][$firstParam]['exclude']);
}
$subMenu['subMenu'] = $this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey];
$subMenu['subMenu'] = $this->lang->admin->menuList->{$menuKey}['tabMenu'][$subMenuKey];
}
if(isset($this->lang->admin->menuList->$menuKey['tabMenu']['menuOrder'][$subMenuKey])) $subMenu['menuOrder'] = $this->lang->admin->menuList->$menuKey['tabMenu']['menuOrder'][$subMenuKey];
if(isset($this->lang->admin->menuList->$menuKey['tabMenu']['dividerMenu'][$subMenuKey])) $subMenu['dividerMenu'] = $this->lang->admin->menuList->$menuKey['tabMenu']['dividerMenu'][$subMenuKey];
if(isset($this->lang->admin->menuList->{$menuKey}['tabMenu']['menuOrder'][$subMenuKey])) $subMenu['menuOrder'] = $this->lang->admin->menuList->{$menuKey}['tabMenu']['menuOrder'][$subMenuKey];
if(isset($this->lang->admin->menuList->{$menuKey}['tabMenu']['dividerMenu'][$subMenuKey])) $subMenu['dividerMenu'] = $this->lang->admin->menuList->{$menuKey}['tabMenu']['dividerMenu'][$subMenuKey];
$this->lang->admin->menu->$subMenuKey = $subMenu;
}
}
if(isset($this->lang->admin->menuList->$menuKey['menuOrder'])) $this->lang->admin->menuOrder = $this->lang->admin->menuList->$menuKey['menuOrder'];
if(isset($this->lang->admin->menuList->$menuKey['dividerMenu'])) $this->lang->admin->dividerMenu = $this->lang->admin->menuList->$menuKey['dividerMenu'];
if(isset($this->lang->admin->menuList->$menuKey['tabMenu'])) $this->lang->admin->tabMenu = $this->lang->admin->menuList->$menuKey['tabMenu'];
if(isset($this->lang->admin->menuList->{$menuKey}['menuOrder'])) $this->lang->admin->menuOrder = $this->lang->admin->menuList->{$menuKey}['menuOrder'];
if(isset($this->lang->admin->menuList->{$menuKey}['dividerMenu'])) $this->lang->admin->dividerMenu = $this->lang->admin->menuList->{$menuKey}['dividerMenu'];
if(isset($this->lang->admin->menuList->{$menuKey}['tabMenu'])) $this->lang->admin->tabMenu = $this->lang->admin->menuList->{$menuKey}['tabMenu'];
}
}
@@ -506,7 +506,7 @@ class adminModel extends model
}
/**
* Get extensions from zentao.net.
* Set extensions from zentao.net.
*
* @param string $type plugin|patch
* @param int $limit
@@ -514,41 +514,22 @@ class adminModel extends model
* @access public
* @return array
*/
public function getExtensionsByAPI($type = 'plugin', $limit = 6, $hasInternet = true)
public function setExtensionsByAPI($type = 'plugin', $limit = 5)
{
if($hasInternet)
$searchType = $type == 'plugin' ? 'byModule,offcial' : 'byModule';
$param = $type == 'plugin' ? '' : 'MTIxOA==';
$extensions = $this->loadModel('extension')->getExtensionsByAPI($searchType, $param, 0, $limit);
$extensions = isset($extensions->extensions) ? (array)$extensions->extensions : array();
$plugins = array();
foreach($extensions as $extension)
{
$searchType = $type == 'plugin' ? 'byUpdatedTime,offcial' : 'byModule';
$param = $type == 'plugin' ? '' : 'MTIxOA==';
$extensions = $this->loadModel('extension')->getExtensionsByAPI($searchType, $param, 0, $limit);
$plugins = isset($extensions->extensions) ? (array)$extensions->extensions : array();
foreach($plugins as $id => $plugin)
{
$plugin->viewLink = str_replace(array('info', 'client'), '', $plugin->viewLink);
if($type == 'patch' and !isset($plugin->compatibleRelease)) unset($plugins[$id]);
}
}
else
{
if($this->config->edition == 'open')
{
$plugins = array(
$this->config->admin->plugins[27],
$this->config->admin->plugins[26],
$this->config->admin->plugins[30]
);
}
else
{
$plugins = array(
$this->config->admin->plugins[198],
$this->config->admin->plugins[194],
$this->config->admin->plugins[203]
);
}
if($type == 'patch' and !isset($extension->compatibleRelease)) continue;
$extension->viewLink = str_replace(array('info', 'client'), '', $extension->viewLink);
$plugins[] = $extension;
}
return $plugins;
return $this->loadModel('block')->setZentaoData($type, $plugins);
}
/**
@@ -572,13 +553,13 @@ class adminModel extends model
}
/**
* Get public class from zentao.net.
* Set public class from zentao.net.
*
* @param int $limit
* @access public
* @return array
* @return void
*/
public function getPublicClassByAPI($limit = 2)
public function setPublicClassByAPI($limit = 3)
{
$apiURL = $this->config->admin->videoAPIURL;
$data = $this->fetchAPI($apiURL);
@@ -596,24 +577,25 @@ class adminModel extends model
$publicClass[$index]->viewLink = $this->config->admin->apiRoot . '/publicclass/' . ($course->alias ? "{$course->alias}-" : '') . "{$course->id}.html";
$index ++;
}
return $publicClass;
return $this->loadModel('block')->setZentaoData('publicclass', $publicClass);
}
/**
* Get dynamics by API.
* Set dynamics by API.
*
* @param int $limit
* @access public
* @return array
* @return void
*/
public function getDynamicsByAPI($limit = 2)
public function setDynamicsByAPI($limit = 2)
{
$apiURL = $this->config->admin->downloadAPIURL;
$data = $this->fetchAPI($apiURL);
$articles = $data->articles;
$index = 1;
$downloads = array();
$index = 1;
$news = array();
foreach($articles as $article)
{
if($index > $limit) break;
@@ -622,14 +604,15 @@ class adminModel extends model
if(!isset($this->lang->admin->$tagKey)) break;
if(!preg_match("/{$this->lang->admin->$tagKey}\d/", $article->title)) continue;
$downloads[$index] = new stdClass();
$downloads[$index]->id = $article->id;
$downloads[$index]->title = $article->title;
$downloads[$index]->addedDate = $article->addedDate;
$downloads[$index]->link = $this->config->admin->apiRoot . "/download/{$article->alias}-{$article->id}.html";
$news[$index] = new stdClass();
$news[$index]->id = $article->id;
$news[$index]->title = $article->title;
$news[$index]->addedDate = $article->addedDate;
$news[$index]->link = $this->config->admin->apiRoot . "/download/{$article->alias}-{$article->id}.html";
$index ++;
}
return $downloads;
return $this->loadModel('block')->setZentaoData('news', $news);
}
/**
@@ -640,10 +623,11 @@ class adminModel extends model
*/
public function checkInternet()
{
$curl = curl_init();
$timeout = 3;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $this->config->admin->apiSite);
curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1000);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 1000);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
@@ -670,4 +654,58 @@ class adminModel extends model
return helper::getDateInterval($firstUseDate);
}
/**
* Get zentao.net data.
*
* @access public
* @return object
*/
public function getZentaoData()
{
$zentaoData = $this->loadModel('block')->getZentaoData();
$data = new stdclass();
$data->hasData = true;
$news = array();
$publicclass = array();
$plugins = array();
$patches = array();
if(empty($zentaoData))
{
$data->hasData = false;
if($this->config->edition == 'open')
{
$plugins = array(
$this->config->admin->plugins[27],
$this->config->admin->plugins[26],
$this->config->admin->plugins[30]
);
}
else
{
$plugins = array(
$this->config->admin->plugins[198],
$this->config->admin->plugins[194],
$this->config->admin->plugins[203]
);
}
}
else
{
$news = json_decode($zentaoData['news']);
$publicclass = json_decode($zentaoData['publicclass']);
$plugins = json_decode($zentaoData['plugin']);
$patches = json_decode($zentaoData['patch']);
if(common::checkNotCN()) array_pop($plugins);
}
$data->news = $news;
$data->publicclass = $publicclass;
$data->plugins = $plugins;
$data->patches = $patches;
return $data;
}
}
+26 -18
View File
@@ -19,11 +19,16 @@
<div class="settings-list <?php if($config->vision == 'lite') echo 'lite-setting';?>">
<?php foreach($lang->admin->menuList as $menuKey => $menu):?>
<?php if($config->vision == 'lite' and !in_array($menuKey, $config->admin->liteMenuList)) continue;?>
<div class="setting-box">
<div class="setting-box" <?php if($menu['disabled']) echo "title={$lang->admin->noPriv}";?> data-id="<?php echo $menuKey;?>">
<button class="btn shadow-primary-hover" <?php if($menu['disabled']) echo 'disabled';?> data-link='<?php echo $menu['link'];?>'>
<h4><img src="/static/svg/admin-<?php echo $menuKey;?>.svg"/><?php echo $menu['name'];?></h4>
<h4 class="flex align-center w-full">
<div class="flex align-center">
<img src="static/svg/admin-<?php echo $menuKey;?>.svg"/>
<?php echo $menu['name'];?>
</div>
<?php echo html::a($config->admin->helpURL[$menuKey], "<i title='{$lang->help}' class='icon icon-help'></i> ", '_blank', 'class="text-muted setting-help"');?>
</h4>
<p class="text-muted setting-desc" title="<?php echo $menu['desc'];?>"><?php echo $menu['desc'];?></p>
<?php echo html::a($config->admin->helpURL[$menuKey], "<i class='icon icon-help'></i> {$lang->help}", '_blank', 'class="text-muted setting-help"');?>
</button>
</div>
<?php endforeach;?>
@@ -40,9 +45,9 @@
<?php foreach($plugins as $plugin):?>
<?php $pluginDesc = preg_replace('/[[:cntrl:]]/mu', '', strip_tags($plugin->abstract));?>
<div class="plugin-item shadow-primary-hover" data-link='<?php echo $plugin->viewLink;?>'>
<a href="<?php echo $plugin->viewLink;?>" class='ext-download' target='_blank'><i class='icon icon-download-alt text-primary bg-primary-100 pd-3'></i></a>
<span class='ext-download'><i class='icon icon-download-alt text-primary bg-primary-100 pd-3'></i></span>
<h4 class="plug-title" title="<?php echo $plugin->name;?>"><?php echo $plugin->name;?></h4>
<p class='extension-desc' title="<?php echo $pluginDesc;?>"><?php echo $pluginDesc;?></p>
<p class='extension-desc text-muted' title="<?php echo $pluginDesc;?>"><?php echo $pluginDesc;?></p>
</div>
<?php endforeach;?>
</div>
@@ -53,19 +58,22 @@
<div class="flex bottom">
<div class="panel official">
<div class="panel-title"><?php echo $lang->admin->officialAccount?></div>
<div class="flex main-panel">
<div class="official-img"></div>
<div class="official-content">
<div class="title">
<?php echo $lang->admin->followUs?>
<?php if(!$hasInternet):?>
<i class="icon follow-us icon-arrow-right text-primary"></i>
<?php endif;?>
<div class="flex main-panel">
<div class="official-img"></div>
<div class="official-content">
<div class="title">
<?php echo $lang->admin->followUs?>
<?php if(!$hasInternet):?>
<i class="icon follow-us icon-arrow-right text-primary"></i>
<?php endif;?>
</div>
<div class="content"> <?php echo $lang->admin->followUsContent?></div>
</div>
<div class="content"> <?php echo $lang->admin->followUsContent?></div>
</div>
</div>
<?php if(!$bind and !$ignore and $hasInternet and common::hasPriv('admin', 'register')):?>
<div class="panel-link"> <?php echo sprintf($lang->admin->notice->register, html::a(inlink('register'), $lang->admin->registerNotice->submitHere, '', 'class="text-primary"'));?></div>
<?php endif;?>
</div>
</div>
<?php if($publicClass):?>
<div class="panel publicClass">
<div class="panel-title">
@@ -75,7 +83,7 @@
<div class="classList flex">
<?php foreach($publicClass as $class):?>
<a class="classItem shadow-primary-hover" href='<?php echo $class->viewLink;?>' target='_blank'>
<div class="imgBack">
<div class="imgBack">
<div class="classImg" style="background-image: url('<?php echo $class->image;?>');"></div>
</div>
<div class="classContent"><?php echo $class->name;?></div>
@@ -110,7 +118,7 @@
</div>
<?php foreach($dynamics as $dynamic):?>
<div class="dynamic-block">
<div class="dynamic-content"><i class="icon icon-horn text-primary pr-4 font-20"></i><?php echo html::a($dynamic->link, $dynamic->title, '_blank');?></div>
<div class="dynamic-content" title=<?php echo $dynamic->title ?>><i class="icon icon-horn text-primary pr-4 font-20"></i><?php echo html::a($dynamic->link, $dynamic->title, '_blank');?></div>
<div class="dynamic-time"><?php echo substr($dynamic->addedDate, 0, 10);?></div>
</div>
<?php endforeach;?>
+3 -1
View File
@@ -23,7 +23,7 @@
</div>
</div>
<div id='mainContent' class='main-row'>
<div class='col-md-6'>
<div <?php if(common::hasPriv('admin', 'bind')) echo "class='col-md-6'";?>>
<div class='panel'>
<div class='panel-heading'><strong><?php echo $lang->admin->registerNotice->common?></strong></div>
<form class='mw-600px' method="post" target="hiddenwin">
@@ -94,6 +94,7 @@
</form>
</div>
</div>
<?php if(common::hasPriv('admin', 'bind')):?>
<div class='col-md-6'>
<div class='panel'>
<div class='panel-heading'><strong><?php echo $lang->admin->registerNotice->bind?></strong></div>
@@ -118,6 +119,7 @@
</form>
</div>
</div>
<?php endif;?>
</div>
<script>
$(function()
-1
View File
@@ -9,7 +9,6 @@
* @version $Id: English.php 824 2010-05-02 15:32:06Z wwccss $
* @link http://www.zentao.net
*/
$lang->api = new stdclass();
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
-1
View File
@@ -9,7 +9,6 @@
* @version $Id: English.php 824 2010-05-02 15:32:06Z wwccss $
* @link http://www.zentao.net
*/
$lang->api = new stdclass();
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
-1
View File
@@ -9,7 +9,6 @@
* @version $Id: English.php 824 2010-05-02 15:32:06Z wwccss $
* @link http://www.zentao.net
*/
$lang->api = new stdclass();
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
-1
View File
@@ -9,7 +9,6 @@
* @version $Id: English.php 824 2010-05-02 15:32:06Z wwccss $
* @link http://www.zentao.net
*/
$lang->api = new stdclass();
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
-1
View File
@@ -9,7 +9,6 @@
* @version $Id: zh-cn.php 5129 2013-07-15 00:16:07Z zhujinyonging@gmail.com $
* @link http://www.zentao.net
*/
$lang->api = new stdclass();
$lang->api->common = 'API接口';
$lang->api->getModel = '超级model调用接口';
$lang->api->sql = 'SQL查询接口';
-1
View File
@@ -9,7 +9,6 @@
* @version $Id: zh-tw.php 5129 2013-07-15 00:16:07Z zhujinyonging@gmail.com $
* @link http://www.zentao.net
*/
$lang->api = new stdclass();
$lang->api->common = 'API介面';
$lang->api->getModel = '超級model調用介面';
$lang->api->sql = 'SQL查詢介面';
+1 -1
View File
@@ -299,7 +299,7 @@ class backupModel extends model
$summaryFile = dirname($backup) . DS . 'summary';
if(!file_exists($summaryFile)) return array();
$summary = json_decode(file_get_contents(dirname($backup) . DS . 'summary'), 'true');
$summary = json_decode(file_get_contents(dirname($backup) . DS . 'summary'), true);
return isset($summary[basename($backup)]) ? $summary[basename($backup)] : array();
}
+36 -8
View File
@@ -78,7 +78,25 @@ class block extends control
elseif(isset($this->lang->block->moduleList[$module]))
{
$this->get->set('mode', 'getblocklist');
if($module == 'project') $this->get->set('dashboard', 'project');
if($module == 'project')
{
$this->get->set('dashboard', 'project');
if($this->config->edition == 'max' and $this->app->tab == 'project')
{
$project = $this->loadModel('project')->getByID($this->session->project);
if(isset($project->model) and !helper::hasFeature("{$project->model}_issue"))
{
unset($this->lang->block->modules['scrum']['index']->availableBlocks->scrumissue);
unset($this->lang->block->modules['waterfall']['index']->availableBlocks->waterfallissue);
}
if(isset($project->model) and !helper::hasFeature("{$project->model}_risk"))
{
unset($this->lang->block->modules['scrum']['index']->availableBlocks->scrumrisk);
unset($this->lang->block->modules['waterfall']['index']->availableBlocks->waterfallrisk);
}
}
}
$this->view->blocks = $this->fetch('block', 'main', "module=$module&id=$id");
$this->view->module = $module;
}
@@ -253,10 +271,20 @@ class block extends control
$shortBlocks = $longBlocks = array();
foreach($blocks as $key => $block)
{
if($block->block == 'waterfallrisk' and !helper::hasFeature('waterfall_risk')) continue;
if($block->block == 'waterfallissue' and !helper::hasFeature('waterfall_issue')) continue;
if($block->block == 'scrumrisk' and !helper::hasFeature('scrum_risk')) continue;
if($block->block == 'scrumissue' and !helper::hasFeature('scrum_issue')) continue;
if(in_array($block->block, array('waterfallrisk', 'waterfallissue')))
{
$model = isset($project->model) ? $project->model : 'waterfall';
if($block->block == 'waterfallrisk' and !helper::hasFeature("{$model}_risk")) continue;
if($block->block == 'waterfallissue' and !helper::hasFeature("{$model}_issue")) continue;
}
if(in_array($block->block, array('scrumrisk', 'scrumissue')))
{
$model = isset($project->model) ? $project->model : 'scrum';
if($block->block == 'scrumrisk' and !helper::hasFeature("{$model}_risk")) continue;
if($block->block == 'scrumissue' and !helper::hasFeature("{$model}_issue")) continue;
}
if(!empty($block->source) and $block->source != 'todo' and !empty($acls['views']) and !isset($acls['views'][$block->source]))
{
unset($blocks[$key]);
@@ -950,14 +978,14 @@ class block extends control
foreach($projects as $projectID => $project)
{
if($project->model == 'scrum' or $project->model == 'kanban')
if(in_array($project->model, array('scrum', 'kanban', 'agileplus')))
{
$this->app->loadClass('pager', $static = true);
$pager = pager::init(0, 3, 1);
$project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100;
$project->executions = $this->execution->getStatData($projectID, 'all', 0, 0, false, '', 'id_desc', $pager);
}
elseif($project->model == 'waterfall')
elseif(in_array($project->model, array('waterfall', 'waterfallplus')))
{
$begin = $project->begin;
$weeks = $this->weekly->getWeekPairs($begin);
@@ -1476,7 +1504,7 @@ class block extends control
$sprints = $this->dao->select('status, count(*) as sprints')->from(TABLE_EXECUTION)
->where('deleted')->eq(0)
->beginIF($this->config->vision == 'lite')->andWhere('type')->eq('kanban')->fi()
->beginIF($this->config->vision == 'rnd')->andWhere('type')->eq('sprint')->fi()
->beginIF($this->config->vision == 'rnd')->andWhere('type')->in('sprint,kanban')->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
->andWhere('project')->eq($this->session->project)
->groupBy('status')
+39
View File
@@ -1072,4 +1072,43 @@ class blockModel extends model
{
return $this->dao->select('count(estimate) as estimate')->from(TABLE_STORY)->where('id')->in($storyID)->fetch('estimate');
}
/**
* Get zentao.net data.
*
* @param string $minTime
* @access public
* @return array
*/
public function getZentaoData($minTime = '')
{
return $this->dao->select('type,params')->from(TABLE_BLOCK)
->where('account')->eq('system')
->andWhere('vision')->eq('rnd')
->andWhere('module')->eq('zentao')
->beginIF($minTime)->andWhere('source')->ge($minTime)->fi()
->andWhere('type')->in('plugin,patch,publicclass,news')
->fetchPairs('type');
}
/**
* Set zentao data.
*
* @param string $type
* @param string $params
* @access public
* @return void
*/
public function setZentaoData($type = 'patch', $params = '')
{
$data = new stdclass();
$data->account = 'system';
$data->vision = 'rnd';
$data->module = 'zentao';
$data->type = $type;
$data->source = date('Y-m-d');
$data->params = json_encode($params);
$this->dao->replace(TABLE_BLOCK)->data($data)->exec();
}
}
-1
View File
@@ -1,4 +1,3 @@
<?php
/**
* The case block view file of block module of ZenTaoPMS.
-1
View File
@@ -28,7 +28,6 @@
.block-guide .tab-pane .app-client .tree-menu li .avatar img {padding: 6px;}
.block-guide .tab-pane .app-client .client-desc {padding-top: 12px;}
.block-guide .tab-pane .app-client .client-desc img {height: 195px;}
.block-guide .tab-pane .app-qrcode {padding: 10px 20px;}
.block-guide .tab-pane .app-qrcode .col-md-12 {padding-left: 0; padding-top: 10px;}
.block-guide .tab-pane .app-qrcode .qrcode-down img {padding-top: 16px;}
.block-guide .tab-pane .app-qrcode .qrcode-down .text-primary {padding-top: 10px;}
+3 -3
View File
@@ -53,7 +53,6 @@
.picker-single .picker-option.picker-option-selected.picker-option-active.option-ursr > .border,
.picker-single .picker-option.picker-option-selected.picker-option-active.option-ursr > .border {
background: rgba(230,240,255, 0.4)!important;
border: 1px solid #2E7FFF;
}
#pickerDropMenu-pk_URSR > .picker-option-list {
display: flex;
@@ -173,7 +172,7 @@ function initPreference() {
$option.addClass('option-ursr');
$option.parent().addClass('list-ursr');
$option.empty();
$option.prepend('<div class="border"><div class="value"><p>' + (b.$_index + 1) + '</p></div><div class="context">' + b.text + '</div></div>');
$option.prepend('<div class="border shadow-primary-hover"><div class="value"><p>' + (b.$_index + 1) + '</p></div><div class="context">' + b.text + '</div></div>');
}
return $option;
}
@@ -204,4 +203,5 @@ $(function()
initPreference();
})
</script>
</script>
+2 -2
View File
@@ -134,7 +134,7 @@ $(function()
<?php foreach($projects as $project):?>
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id='<?php echo "tab3{$blockNavId}Content{$project->id}";?>'>
<div class="table-row">
<?php if($project->model == 'scrum' or $project->model == 'kanban'):?>
<?php if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))):?>
<div class='table-row'>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->storyCount;?></h4></div>
@@ -205,7 +205,7 @@ $(function()
<div class='col-7'>
<div class='progress progress-text-left'>
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->executions[0]->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->executions[0]->hours->progress;?>%">
<span class='progress-text'><?php echo $project->executions[0]->hours->progress . '%';?></span>
<span class='progress-text'><?php echo !empty($project->executions[0]->hours->progress) ? $project->executions[0]->hours->progress . '%' : '0%';?></span>
</div>
</div>
</div>
Regular → Executable
+1 -1
View File
@@ -223,7 +223,7 @@ $config->bug->datatable->fieldList['execution']['title'] = 'execution';
$config->bug->datatable->fieldList['execution']['fixed'] = 'no';
$config->bug->datatable->fieldList['execution']['width'] = '120';
$config->bug->datatable->fieldList['execution']['required'] = 'no';
$config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'product', 'method' =>'getAllExecutionPairsByProduct', 'params' => '$productID&$branch');
$config->bug->datatable->fieldList['execution']['dataSource'] = array('module' => 'product', 'method' =>'getAllExecutionPairsByProduct', 'params' => '$productID&$branch&0&stagefilter');
$config->bug->datatable->fieldList['plan']['title'] = 'plan';
$config->bug->datatable->fieldList['plan']['fixed'] = 'no';
+7 -4
View File
@@ -636,7 +636,7 @@ class bug extends control
/* Get executions. */
$executions = array(0 => '');
if(isset($projects[$projectID])) $executions += $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID, !$projectID ? 'multiple' : '');
if(isset($projects[$projectID])) $executions += $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID, !$projectID ? 'multiple|stagefilter' : 'stagefilter');
$execution = $executionID ? $this->loadModel('execution')->getByID($executionID) : '';
$executions = isset($executions[$executionID]) ? $executions : $executions + array($executionID => $execution->name);
@@ -859,7 +859,7 @@ class bug extends control
$this->view->users = $this->user->getPairs('devfirst|noclosed');
$this->view->projects = array('' => '') + $this->product->getProjectPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID);
$this->view->projectID = $projectID;
$this->view->executions = array('' => '') + $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID, 'multiple');
$this->view->executions = array('' => '') + $this->product->getExecutionPairsByProduct($productID, $branch ? "0,$branch" : 0, 'id_desc', $projectID, 'multiple,stagefilter');
$this->view->executionID = $executionID;
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch === 'all' ? 0 : $branch);
$this->view->moduleID = $moduleID;
@@ -1165,6 +1165,9 @@ class bug extends control
$productBugs = $this->bug->getProductBugPairs($productID, $branch);
unset($productBugs[$bugID]);
$executions = array(0 => '') + $this->product->getExecutionPairsByProduct($bug->product, $bug->branch, 'id_desc', $bug->project);
if(!empty($bug->execution) and empty($executions[$bug->execution])) $executions[$execution->id] = $execution->name;
if($product->shadow) $this->view->project = $this->loadModel('project')->getByShadowProduct($bug->product);
$this->view->bug = $bug;
@@ -1177,7 +1180,7 @@ class bug extends control
$this->view->projectExecutionPairs = $this->loadModel('project')->getProjectExecutionPairs();
$this->view->moduleOptionMenu = $moduleOptionMenu;
$this->view->currentModuleID = $currentModuleID;
$this->view->executions = array(0 => '') + $this->product->getExecutionPairsByProduct($bug->product, $bug->branch, 'id_desc', $bug->project);
$this->view->executions = $executions;
$this->view->stories = $bug->execution ? $this->story->getExecutionStoryPairs($bug->execution) : $this->story->getProductStoryPairs($bug->product, $bug->branch, 0, 'all', 'id_desc', 0, 'full', 'story', false);
$this->view->branchOption = $branchOption;
$this->view->branchTagOption = $branchTagOption;
@@ -1398,7 +1401,7 @@ class bug extends control
}
/* Set users. */
$users = $this->user->getPairs('devfirst', '', $this->config->maxCount);
$users = $this->user->getPairs('devfirst');
$users = array('' => '', 'ditto' => $this->lang->bug->ditto) + $users;
/* Assign. */
+1 -1
View File
@@ -369,7 +369,7 @@ function loadProductExecutions(productID, projectID = 0)
var execution = $('#execution').val();
}
link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID + '&branch=' + branch + '&number=&executionID=' + execution);
link = createLink('product', 'ajaxGetExecutions', 'productID=' + productID + '&projectID=' + projectID + '&branch=' + branch + '&number=&executionID=' + execution + '&from=&mode=stagefilter');
$('#executionIdBox').load(link, function()
{
$(this).find('select').chosen();
+5
View File
@@ -3704,6 +3704,11 @@ class bugModel extends model
if($type == 'view' && $this->app->tab != 'product')
{
$tab = $this->app->tab == 'qa' ? 'product' : $this->app->tab;
if($tab == 'product')
{
$product = $this->loadModel('product')->getByID($bug->product);
if(!empty($product->shadow)) $tab = 'project';
}
$menu .= $this->buildMenu('bug', 'toStory', $toStoryParams, $bug, $type, $this->lang->icons['story'], '', '', '', "data-app='$tab' id='tostory'", $this->lang->bug->toStory);
if(common::hasPriv('task', 'create') and !isonlybody()) $menu .= html::a('#toTask', "<i class='icon icon-check'></i><span class='text'>{$this->lang->bug->toTask}</span>", '', "data-app='qa' data-toggle='modal' class='btn btn-link'");
$menu .= $this->buildMenu('bug', 'createCase', $convertParams, $bug, $type, 'sitemap');
-3
View File
@@ -74,9 +74,6 @@
</thead>
<tbody>
<?php foreach($bugs as $bugID => $bug):?>
<?php
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["assignedTos[$bugID]"] = $this->config->user->moreLink;
?>
<tr>
<td><?php echo $bugID . html::hidden("bugIDList[$bugID]", $bugID);?></td>
<td <?php echo zget($visibleFields, 'type', "class='hidden'")?>><?php echo html::select("types[$bugID]", $typeList, $bug->type, 'class=form-control');?></td>
+1 -1
View File
@@ -125,7 +125,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</div>
</td>
</tr>
<tr class='<?php if(!($product->shadow and zget($project, 'model') == 'scrum' and $project->multiple)) echo 'hide'?>'>
<tr class='<?php if($product->shadow and isset($project) and !$project->multiple) echo 'hide'?>'>
<th><?php echo $lang->bug->productplan;?></th>
<td>
<span id="planIdBox"><?php echo html::select('plan', $plans, $bug->plan, "class='form-control chosen'");?></span>
+1 -1
View File
@@ -161,7 +161,7 @@
<th><?php echo $lang->bug->fromCase;?></th>
<td><?php if($bug->case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion", '', true), "<i class='icon icon-sitemap'></i> {$lang->bug->fromCase}$lang->colon$bug->case", '', isonlybody() ? '' : "data-toggle='modal' data-type='iframe' data-width='80%'");?></td>
</tr>
<tr valign='middle' class='<?php if(!($product->shadow and zget($project, 'model') == 'scrum' and $project->multiple)) echo 'hide'?>'>
<tr valign='middle' class='<?php if($product->shadow and isset($project) and !$project->multiple) echo 'hide'?>'>
<th><?php echo $lang->bug->productplan;?></th>
<td><?php if(!$bug->plan or !common::printLink('productplan', 'view', "planID=$bug->plan&type=bug", $bug->planName)) echo $bug->planName;?></td>
</tr>
+9 -7
View File
@@ -66,24 +66,25 @@ class build extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('build', 'view', "buildID=$buildID") . "#app={$this->app->tab}"));
}
$status = empty($this->config->CRProduct) ? 'noclosed' : '';
$this->loadModel('product');
$this->loadModel('project');
/* Set menu. */
if($this->app->tab == 'project')
{
$this->project->setMenu($projectID);
$executions = $this->execution->getPairs($projectID, 'all', 'stagefilter|leaf');
$executions = $this->execution->getPairs($projectID, 'all', 'stagefilter|leaf|order_asc');
$executionID = empty($executionID) ? key($executions) : $executionID;
$productGroups = $executionID ? $this->product->getProducts($executionID) : array();
$productGroups = $executionID ? $this->product->getProducts($executionID, $status) : array();
$branchGroups = $executionID ? $this->project->getBranchesByProject($executionID) : array();
$this->session->set('project', $projectID);
}
elseif($this->app->tab == 'execution')
{
$execution = $this->execution->getByID($executionID);
$executions = $this->execution->getPairs($execution->project, 'all', 'stagefilter|leaf');
$executions = $this->execution->getPairs($execution->project, 'all', 'stagefilter|leaf|order_asc');
$projectID = $execution->project;
$productGroups = $this->product->getProducts($executionID);
$productGroups = $this->product->getProducts($executionID, $status);
$branchGroups = $this->project->getBranchesByProject($executionID);
$this->execution->setMenu($executionID);
$this->session->set('project', $execution->project);
@@ -93,7 +94,7 @@ class build extends control
$execution = $this->execution->getByID($executionID);
$projectID = $execution ? $execution->project : 0;
$executions = $this->execution->getPairs($projectID, 'all', 'stagefilter|leaf');
$productGroups = $this->product->getProducts($executionID);
$productGroups = $this->product->getProducts($executionID, $status);
$branchGroups = $this->project->getBranchesByProject($executionID);
}
@@ -171,14 +172,15 @@ class build extends control
if($this->app->tab == 'execution') $this->execution->setMenu($build->execution);
$builds = array();
$status = empty($this->config->CRProduct) ? 'noclosed' : '';
if($build->execution)
{
$productGroups = $this->product->getProducts($build->execution);
$productGroups = $this->product->getProducts($build->execution, $status);
$branches = $this->loadModel('branch')->getList($build->product, $build->execution, 'all');
}
else
{
$productGroups = $this->product->getProducts($build->project);
$productGroups = $this->product->getProducts($build->project, $status);
$branches = $this->loadModel('branch')->getList($build->product, $build->project, 'all');
$builds = $this->build->getBuildPairs($build->product, 'all', 'noempty,notrunk,singled,separate', $build->project, 'project', $build->builds, false);
}
+33
View File
@@ -69,3 +69,36 @@ $(function()
}
});
})
/**
* Delete item use ajax.
*
* @param string url
* @param string replaceID
* @param string notice
* @access public
* @return void
*/
function ajaxDelete(url, replaceID, notice)
{
if(confirm(notice))
{
$.ajax(
{
type: 'GET',
url: url,
dataType: 'json',
success: function(data)
{
if(data.result == 'success')
{
location.reload();
}
else if(data.result == 'fail' && typeof(data.message) == 'string')
{
bootbox.alert(data.message);
}
}
});
}
}
+7 -4
View File
@@ -112,6 +112,7 @@ class buildModel extends model
$buildQuery = str_replace($field, "t1." . $field, $buildQuery);
}
}
if(strpos($this->session->projectBuildQuery, 'execution') !== false) $buildQuery = str_replace('`execution`', 't2.`id`', $buildQuery);
return $this->getProjectBuilds($projectID, 'bysearch', $buildQuery);
}
@@ -478,11 +479,13 @@ class buildModel extends model
*/
public function update($buildID)
{
$buildID = (int)$buildID;
$oldBuild = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch();
$build = fixer::input('post')->stripTags($this->config->build->editor->edit['id'], $this->config->allowedTags)
$buildID = (int)$buildID;
$oldBuild = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch();
$newProduct = $this->dao->select('id,type')->from(TABLE_PRODUCT)->where('id')->eq($_POST['product'])->fetchPairs();
$branch = (!isset($_POST['branch']) or $newProduct == 'normal') ? 0 : $oldBuild->branch;
$build = fixer::input('post')->stripTags($this->config->build->editor->edit['id'], $this->config->allowedTags)
->add('id', $buildID)
->setIF(!isset($_POST['branch']), 'branch', $oldBuild->branch)
->setDefault('branch', $branch)
->setDefault('product', $oldBuild->product)
->setDefault('builds', '')
->cleanInt('product,execution')
-1
View File
@@ -36,7 +36,6 @@
</td>
<td><?php if($disabled) echo $lang->build->notice->changeProduct;?></td>
</tr>
<tr>
<tr class='<?php if((!empty($product) and $product->type == 'normal') or empty($product) or empty($build->execution)) echo 'hidden'?>'>
<?php
if(empty($product)) $product = new stdclass();
+4 -1
View File
@@ -385,7 +385,10 @@ tbody tr td:first-child input {display: none;}
<?php if($build->execution):?>
<tr>
<th><?php echo empty($multipleProject) ? $lang->build->project :($executionType ? $lang->build->executionAB : $lang->build->execution);?></th>
<td><?php echo zget($executions, $build->execution);?></td>
<td>
<?php $executionName = zget($executions, $build->execution);?>
<?php echo ltrim($executionName, '/');?>
</td>
</tr>
<?php else:?>
<tr>
+44 -39
View File
@@ -49,43 +49,44 @@ $lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar
$lang->agreement = "I have read and agreed to the terms and conditions of <a href='http://zpl.pub/page/zplv12.html' target='_blank'> Z PUBLIC LICENSE 1.2 </a>. <span class='text-danger'>Without authorization, I should not remove, hide or cover any logos/links of ZenTao.</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> AIUX</a>";
$lang->reset = 'Zurücksetzen';
$lang->cancel = 'Abbrechen';
$lang->refresh = 'Aktualisieren';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = 'Create';
$lang->edit = 'Bearbeiten';
$lang->delete = 'Löschen';
$lang->activate = 'Activate';
$lang->close = 'Schließen';
$lang->unlink = 'Entfernen';
$lang->import = 'Importieren';
$lang->export = 'Exportieren';
$lang->setFileName = 'Dateiame';
$lang->submitting = 'Speichern...';
$lang->save = 'Speichern';
$lang->confirm = 'Bestätigen';
$lang->preview = 'Ansehen';
$lang->goback = 'Zurück';
$lang->goPC = 'PC';
$lang->more = 'Mehr';
$lang->moreLink = 'MORE';
$lang->day = 'Tag';
$lang->customConfig = 'Custom Config';
$lang->public = 'Öffentlich';
$lang->trunk = 'Trunk';
$lang->sort = 'Sortieren';
$lang->required = 'Pflicht';
$lang->noData = 'Kein Datensatz';
$lang->fullscreen = 'Fullscreen';
$lang->retrack = 'Retrack';
$lang->whitelist = 'Weiße Liste';
$lang->globalSetting = 'Common';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->agilePlusModel = 'Agile Plus';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
$lang->reset = 'Zurücksetzen';
$lang->cancel = 'Abbrechen';
$lang->refresh = 'Aktualisieren';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = 'Create';
$lang->edit = 'Bearbeiten';
$lang->delete = 'Löschen';
$lang->activate = 'Activate';
$lang->close = 'Schließen';
$lang->unlink = 'Entfernen';
$lang->import = 'Importieren';
$lang->export = 'Exportieren';
$lang->setFileName = 'Dateiame';
$lang->submitting = 'Speichern...';
$lang->save = 'Speichern';
$lang->confirm = 'Bestätigen';
$lang->preview = 'Ansehen';
$lang->goback = 'Zurück';
$lang->goPC = 'PC';
$lang->more = 'Mehr';
$lang->moreLink = 'MORE';
$lang->day = 'Tag';
$lang->customConfig = 'Custom Config';
$lang->public = 'Öffentlich';
$lang->trunk = 'Trunk';
$lang->sort = 'Sortieren';
$lang->required = 'Pflicht';
$lang->noData = 'Kein Datensatz';
$lang->fullscreen = 'Fullscreen';
$lang->retrack = 'Retrack';
$lang->whitelist = 'Weiße Liste';
$lang->globalSetting = 'Common';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->agilePlusModel = 'Agile Plus';
$lang->waterfallPlusModel = 'Waterfall Plus';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
$lang->actions = 'Aktionen';
$lang->restore = 'Wiederherstellen';
@@ -188,6 +189,7 @@ $lang->team->common = 'Team';
$lang->user->common = 'User';
$lang->custom->common = 'Custom';
$lang->custom->mode = 'Mode';
$lang->custom->flow = 'Concept';
$lang->extension->common = 'Extension';
$lang->company->common = 'Company';
$lang->dept->common = 'Dept';
@@ -200,7 +202,9 @@ $lang->design->DDS = 'DDS';
$lang->design->DBDS = 'DBDS';
$lang->design->ADS = 'ADS';
$lang->stage->common = 'Stage';
$lang->stage->type = 'Stage Type';
$lang->stage->list = 'Stage List';
$lang->stage->percent = 'Workload Ratio';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->kanban->common = 'Kanban';
$lang->backup->common = 'Backup';
@@ -251,7 +255,8 @@ $lang->indexPage = 'Index';
$lang->model = 'Model';
$lang->redev = 'Develop';
$lang->browser = 'Browser';
$lang->database = 'Database';
$lang->api->doc = 'API Document';
$lang->database = 'Data Dictionary';
$lang->editor = 'Editor';
$lang->timezone = 'Timezone';
$lang->security = 'Security';
@@ -301,7 +306,7 @@ $lang->devops->set = 'Set';
$lang->admin->module = 'Module';
$lang->admin->system = 'System';
$lang->admin->entry = 'Application';
$lang->admin->entry = 'Access ZenTao';
$lang->admin->data = 'Data';
$lang->admin->cron = 'Cron';
$lang->admin->buildIndex = 'Full Text Search';
+44 -39
View File
@@ -49,43 +49,44 @@ $lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar
$lang->agreement = "I have read and agreed to the terms and conditions. <span class='text-danger'>Without authorization, I should not remove, hide or cover any logos/links of ZenTao.</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> AIUX</a>";
$lang->reset = 'Reset';
$lang->cancel = 'Cancel';
$lang->refresh = 'Refresh';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = 'Create';
$lang->edit = 'Edit';
$lang->delete = 'Delete';
$lang->activate = 'Activate';
$lang->close = 'Close';
$lang->unlink = 'Unlink';
$lang->import = 'Import';
$lang->export = 'Export';
$lang->setFileName = 'File Name';
$lang->submitting = 'Saving...';
$lang->save = 'Save';
$lang->confirm = 'Confirm';
$lang->preview = 'View';
$lang->goback = 'Back';
$lang->goPC = 'PC';
$lang->more = 'More';
$lang->moreLink = 'MORE';
$lang->day = ' Day';
$lang->customConfig = 'Custom Config';
$lang->public = 'Public';
$lang->trunk = 'Trunk';
$lang->sort = 'Order';
$lang->required = 'Required';
$lang->noData = 'No data.';
$lang->fullscreen = 'Fullscreen';
$lang->retrack = 'Retrack';
$lang->whitelist = 'Access whitelist';
$lang->globalSetting = 'Common';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->agilePlusModel = 'Agile Plus';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
$lang->reset = 'Reset';
$lang->cancel = 'Cancel';
$lang->refresh = 'Refresh';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = 'Create';
$lang->edit = 'Edit';
$lang->delete = 'Delete';
$lang->activate = 'Activate';
$lang->close = 'Close';
$lang->unlink = 'Unlink';
$lang->import = 'Import';
$lang->export = 'Export';
$lang->setFileName = 'File Name';
$lang->submitting = 'Saving...';
$lang->save = 'Save';
$lang->confirm = 'Confirm';
$lang->preview = 'View';
$lang->goback = 'Back';
$lang->goPC = 'PC';
$lang->more = 'More';
$lang->moreLink = 'MORE';
$lang->day = ' Day';
$lang->customConfig = 'Custom Config';
$lang->public = 'Public';
$lang->trunk = 'Trunk';
$lang->sort = 'Order';
$lang->required = 'Required';
$lang->noData = 'No data.';
$lang->fullscreen = 'Fullscreen';
$lang->retrack = 'Retrack';
$lang->whitelist = 'Access whitelist';
$lang->globalSetting = 'Common';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->agilePlusModel = 'Agile Plus';
$lang->waterfallPlusModel = 'Waterfall Plus';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
$lang->actions = 'Action';
$lang->restore = 'Reset';
@@ -188,6 +189,7 @@ $lang->team->common = 'Team';
$lang->user->common = 'User';
$lang->custom->common = 'Custom';
$lang->custom->mode = 'Mode';
$lang->custom->flow = 'Concept';
$lang->extension->common = 'Extension';
$lang->company->common = 'Company';
$lang->dept->common = 'Dept';
@@ -200,7 +202,9 @@ $lang->design->DDS = 'Detailed Design';
$lang->design->DBDS = 'Database Design';
$lang->design->ADS = 'Interface Design';
$lang->stage->common = 'Stage';
$lang->stage->type = 'Stage Type';
$lang->stage->list = 'Stage List';
$lang->stage->percent = 'Workload Ratio';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->kanban->common = 'Kanban';
$lang->backup->common = 'Backup';
@@ -251,7 +255,8 @@ $lang->indexPage = 'Index';
$lang->model = 'Model';
$lang->redev = 'Develop';
$lang->browser = 'Browser';
$lang->database = 'Database';
$lang->api->doc = 'API Document';
$lang->database = 'Data Dictionary';
$lang->editor = 'Editor';
$lang->timezone = 'Timezone';
$lang->security = 'Security';
@@ -301,7 +306,7 @@ $lang->devops->set = 'Set';
$lang->admin->module = 'Module';
$lang->admin->system = 'System';
$lang->admin->entry = 'Application';
$lang->admin->entry = 'Access ZenTao';
$lang->admin->data = 'Data';
$lang->admin->cron = 'Cron';
$lang->admin->buildIndex = 'Full Text Search';
+44 -39
View File
@@ -49,43 +49,44 @@ $lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar
$lang->agreement = "J'ai lu et j'accepte les termes et conditions de la <a href='http://zpl.pub/page/zplv12.html' target='_blank'> Z PUBLIC LICENSE 1.2 </a>. <span class='text-danger'>Sans autorisation, je ne dois pas supprimer, masquer ou couvrir les logos / liens de ZenTao.</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> AIUX</a>";
$lang->reset = 'Réinitialiser';
$lang->cancel = 'Annuler';
$lang->refresh = 'Rafraichir';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = 'Create';
$lang->edit = 'Editer';
$lang->delete = 'Supprimer';
$lang->activate = 'Activate';
$lang->close = 'Fermer';
$lang->unlink = 'Dissocier';
$lang->import = 'Importer';
$lang->export = 'Exporter';
$lang->setFileName = 'Nom du Fichier';
$lang->submitting = 'Enregistrement...';
$lang->save = 'Sauvegarde';
$lang->confirm = 'Confirmer';
$lang->preview = 'Consulter';
$lang->goback = 'Retour';
$lang->goPC = 'PC';
$lang->more = 'Plus';
$lang->moreLink = 'MORE';
$lang->day = 'Jour';
$lang->customConfig = 'Personnalisation';
$lang->public = 'Public';
$lang->trunk = 'Tronc';
$lang->sort = 'Ordre';
$lang->required = 'Obligatoire';
$lang->noData = 'No data.';
$lang->fullscreen = 'Plein Ecran';
$lang->retrack = 'Réduire';
$lang->whitelist = 'Liste blanche';
$lang->globalSetting = 'Common';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->agilePlusModel = 'Agile Plus';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
$lang->reset = 'Réinitialiser';
$lang->cancel = 'Annuler';
$lang->refresh = 'Rafraichir';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = 'Create';
$lang->edit = 'Editer';
$lang->delete = 'Supprimer';
$lang->activate = 'Activate';
$lang->close = 'Fermer';
$lang->unlink = 'Dissocier';
$lang->import = 'Importer';
$lang->export = 'Exporter';
$lang->setFileName = 'Nom du Fichier';
$lang->submitting = 'Enregistrement...';
$lang->save = 'Sauvegarde';
$lang->confirm = 'Confirmer';
$lang->preview = 'Consulter';
$lang->goback = 'Retour';
$lang->goPC = 'PC';
$lang->more = 'Plus';
$lang->moreLink = 'MORE';
$lang->day = 'Jour';
$lang->customConfig = 'Personnalisation';
$lang->public = 'Public';
$lang->trunk = 'Tronc';
$lang->sort = 'Ordre';
$lang->required = 'Obligatoire';
$lang->noData = 'No data.';
$lang->fullscreen = 'Plein Ecran';
$lang->retrack = 'Réduire';
$lang->whitelist = 'Liste blanche';
$lang->globalSetting = 'Common';
$lang->waterfallModel = 'Waterfall';
$lang->scrumModel = 'Scrum';
$lang->agilePlusModel = 'Agile Plus';
$lang->waterfallPlusModel = 'Waterfall Plus';
$lang->all = 'All';
$lang->viewDetails = 'View Details';
$lang->actions = 'Action';
$lang->restore = 'Réinitialiser';
@@ -188,6 +189,7 @@ $lang->team->common = 'Team';
$lang->user->common = 'User';
$lang->custom->common = 'Custom';
$lang->custom->mode = 'Mode';
$lang->custom->flow = 'Concept';
$lang->extension->common = 'Extension';
$lang->company->common = 'Company';
$lang->dept->common = 'Dept';
@@ -200,7 +202,9 @@ $lang->design->DDS = 'DDS';
$lang->design->DBDS = 'DBDS';
$lang->design->ADS = 'ADS';
$lang->stage->common = 'Stage';
$lang->stage->type = 'Stage Type';
$lang->stage->list = 'Stage List';
$lang->stage->percent = 'Workload Ratio';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->kanban->common = 'Kanban';
$lang->backup->common = 'Backup';
@@ -251,7 +255,8 @@ $lang->indexPage = 'Index';
$lang->model = 'Model';
$lang->redev = 'Develop';
$lang->browser = 'Browser';
$lang->database = 'Database';
$lang->api->doc = 'API Document';
$lang->database = 'Data Dictionary';
$lang->editor = 'Editor';
$lang->timezone = 'Timezone';
$lang->security = 'Security';
@@ -301,7 +306,7 @@ $lang->devops->set = 'Set';
$lang->admin->module = 'Module';
$lang->admin->system = 'System';
$lang->admin->entry = 'Application';
$lang->admin->entry = 'Access ZenTao';
$lang->admin->data = 'Data';
$lang->admin->cron = 'Cron';
$lang->admin->buildIndex = 'Full Text Search';
+5 -5
View File
@@ -539,7 +539,7 @@ $lang->doc->menu->api['subMenu']->struct = array('link' => "{$lang->doc->apiStru
/* Report menu.*/
$lang->report->menu = new stdclass();
$lang->report->menu->screen = array('link' => "{$lang->screen->common}|screen|browse");
$lang->report->menu->pivotTable = array('link' => "{$lang->report->pivotTable}|report|preview");
$lang->report->menu->pivotTable = array('link' => "{$lang->report->pivotTable}|report|productsummary", 'alias' => 'projectdeviation,bugcreate,workload,bugassign');
/* Report menu order. */
$lang->report->menuOrder[5] = 'screen';
@@ -547,10 +547,10 @@ $lang->report->menuOrder[10] = 'pivotTable';
/*
$lang->report->menu->pivotTable['subMenu'] = new stdclass();
$lang->report->menu->pivotTable['subMenu']->product = array('link' => "{$lang->product->common}|report|preview|dimension=&group=product");
$lang->report->menu->pivotTable['subMenu']->project = array('link' => "{$lang->project->common}|report|preview|dimension=&group=project");
$lang->report->menu->pivotTable['subMenu']->test = array('link' => "{$lang->qa->common}|report|preview|dimension=&group=test");
$lang->report->menu->pivotTable['subMenu']->staff = array('link' => "{$lang->system->common}|report|preview|dimension=&group=staff");
$lang->report->menu->pivotTable['subMenu']->product = array('link' => "{$lang->product->common}|report|productsummary");
$lang->report->menu->pivotTable['subMenu']->project = array('link' => "{$lang->project->common}|report|projectdeviation");
$lang->report->menu->pivotTable['subMenu']->test = array('link' => "{$lang->qa->common}|report|bugcreate", 'alias' => 'bugassign');
$lang->report->menu->pivotTable['subMenu']->staff = array('link' => "{$lang->system->common}|report|workload");
$lang->report->menu->pivotTable['menuOrder'][5] = 'product';
$lang->report->menu->pivotTable['menuOrder'][10] = 'project';
+44 -39
View File
@@ -49,43 +49,44 @@ $lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar
$lang->agreement = "已阅读并同意。<span class='text-danger'>未经许可,不得去除、隐藏或遮掩禅道软件的任何标志及链接。</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> 艾体验设计</a>";
$lang->reset = '重填';
$lang->cancel = '取消';
$lang->refresh = '刷新';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = '新建';
$lang->edit = '编辑';
$lang->delete = '删除';
$lang->activate = '激活';
$lang->close = '关闭';
$lang->unlink = '移除';
$lang->import = '导入';
$lang->export = '导出';
$lang->setFileName = '文件名:';
$lang->submitting = '稍候...';
$lang->save = '保存';
$lang->confirm = '确认';
$lang->preview = '查看';
$lang->goback = '返回';
$lang->goPC = 'PC版';
$lang->more = '更多';
$lang->moreLink = 'More';
$lang->day = '天';
$lang->customConfig = '自定义';
$lang->public = '公共';
$lang->trunk = '主干';
$lang->sort = '排序';
$lang->required = '必填';
$lang->noData = '暂无';
$lang->fullscreen = '全屏';
$lang->retrack = '收起';
$lang->whitelist = '访问白名单';
$lang->globalSetting = '通用';
$lang->waterfallModel = '瀑布模型';
$lang->scrumModel = '敏捷模型';
$lang->agilePlusModel = '融合敏捷模型';
$lang->all = '所有';
$lang->viewDetails = '查看详情';
$lang->reset = '重填';
$lang->cancel = '取消';
$lang->refresh = '刷新';
$lang->refreshIcon = "<i title='$lang->refresh' class='icon icon-refresh'></i>";
$lang->create = '新建';
$lang->edit = '编辑';
$lang->delete = '删除';
$lang->activate = '激活';
$lang->close = '关闭';
$lang->unlink = '移除';
$lang->import = '导入';
$lang->export = '导出';
$lang->setFileName = '文件名:';
$lang->submitting = '稍候...';
$lang->save = '保存';
$lang->confirm = '确认';
$lang->preview = '查看';
$lang->goback = '返回';
$lang->goPC = 'PC版';
$lang->more = '更多';
$lang->moreLink = 'More';
$lang->day = '天';
$lang->customConfig = '自定义';
$lang->public = '公共';
$lang->trunk = '主干';
$lang->sort = '排序';
$lang->required = '必填';
$lang->noData = '暂无';
$lang->fullscreen = '全屏';
$lang->retrack = '收起';
$lang->whitelist = '访问白名单';
$lang->globalSetting = '通用';
$lang->waterfallModel = '瀑布模型';
$lang->scrumModel = '敏捷模型';
$lang->agilePlusModel = '融合敏捷模型';
$lang->waterfallPlusModel = '融合瀑布模型';
$lang->all = '所有';
$lang->viewDetails = '查看详情';
$lang->actions = '操作';
$lang->restore = '恢复默认';
@@ -188,6 +189,7 @@ $lang->team->common = '团队';
$lang->user->common = '用户';
$lang->custom->common = '自定义';
$lang->custom->mode = '模式';
$lang->custom->flow = '流程设置';
$lang->extension->common = '插件';
$lang->company->common = '公司';
$lang->dept->common = '部门';
@@ -200,7 +202,9 @@ $lang->design->DDS = '详细设计';
$lang->design->DBDS = '数据库设计';
$lang->design->ADS = '接口设计';
$lang->stage->common = '阶段';
$lang->stage->type = '阶段类型';
$lang->stage->list = '阶段列表';
$lang->stage->percent = '工作量占比';
$lang->execution->list = "{$lang->executionCommon}列表";
$lang->kanban->common = '看板';
$lang->backup->common = '备份';
@@ -251,7 +255,8 @@ $lang->indexPage = '首页';
$lang->model = '模型';
$lang->redev = '二次开发';
$lang->browser = '浏览器';
$lang->database = '数据库';
$lang->api->doc = '接口文档';
$lang->database = '数据字典';
$lang->editor = '编辑器';
$lang->timezone = '时区';
$lang->security = '安全';
@@ -301,7 +306,7 @@ $lang->devops->set = '设置';
$lang->admin->module = '功能配置';
$lang->admin->system = '系统';
$lang->admin->entry = '应用';
$lang->admin->entry = '接入禅道';
$lang->admin->data = '数据';
$lang->admin->cron = '定时';
$lang->admin->buildIndex = '重建索引';
+8 -5
View File
@@ -156,10 +156,8 @@ class commonModel extends model
$this->loadModel('action')->create('execution', $parentExecutionID, 'syncexecutionbychild');
}
if($execution->type == 'stage')
{
$this->loadModel('programplan')->computeProgress($execution->id);
}
$project = $this->loadModel('project')->getByID($execution->project);
if($project->model == 'waterfall' or $project->model == 'waterfallplus') $this->loadModel('programplan')->computeProgress($execution->id);
return $parentExecution;
}
@@ -1791,7 +1789,12 @@ EOD;
$executionPairs = array();
$userCondition = !$app->user->admin ? " AND `id` " . helper::dbIN($app->user->view->sprints) : '';
$orderBy = $object->type == 'stage' ? 'ORDER BY `id` ASC' : 'ORDER BY `id` DESC';
$executionList = $app->dbh->query("SELECT id,name,parent FROM " . TABLE_EXECUTION . " WHERE `project` = '{$object->project}' AND `deleted` = '0' $userCondition $orderBy")->fetchAll();
$executionList = $app->dbh->query("SELECT id,name,parent,project FROM " . TABLE_EXECUTION . " WHERE `project` = '{$object->project}' AND `deleted` = '0' $userCondition $orderBy")->fetchAll();
$executions = array();
foreach($executionList as $execution) $executions[$execution->id] = $execution;
$executionList = $app->control->loadModel('execution')->resetExecutionSorts($executions);
foreach($executionList as $execution)
{
if(isset($executionPairs[$execution->parent])) unset($executionPairs[$execution->parent]);
+1 -1
View File
@@ -222,7 +222,7 @@ function renderExecutionItem(item, $item)
if(!$title.length)
{
if((item.type == 'kanban' && window.userPrivs.kanban) || (item.type != 'kanban' && window.userPrivs.execution))
if(!item.hasOwnProperty('children') && ((item.type == 'kanban' && window.userPrivs.kanban) || (item.type != 'kanban' && window.userPrivs.execution)))
{
var method = item.type == 'kanban' ? 'kanban' : 'task';
+2 -2
View File
@@ -224,9 +224,9 @@ class company extends control
/* Get executions' list.*/
$executions = $this->loadModel('execution')->getPairs(0, 'all', 'nocode|multiple');
$executionList = $this->execution->getByIdList(array_keys($executions));
foreach($executionList as $executionID => $execution)
foreach($executionList as $id => $execution)
{
if(isset($projects[$execution->project])) $executions[$execution->id] = $projects[$execution->project] . $executions[$execution->id];
if(isset($projects[$execution->project])) $executions[$execution->id] = $projects[$execution->project] . $executions[$execution->id];
}
$executions = array($this->lang->execution->common) + $executions;
+1
View File
@@ -0,0 +1 @@
.picker-drop-menu{max-width:300px !important;}
+1 -1
View File
@@ -46,7 +46,7 @@ class convertModel extends model
public function dbExists($dbName = '')
{
$statement = $this->dbh->prepare('SHOW DATABASES like ?');
$statement->execute([$dbName]);
$statement->execute(array($dbName));
return $statement->fetch();
}
+2 -2
View File
@@ -41,8 +41,8 @@ li .form-control {margin-top: 10px}
</ol>
</div>
<hr />
<div class='panel-footer text-center'>
<?php echo html::submitButton($lang->convert->jira->next);?>
<div class='panel-footer text-center form-actions'>
<?php echo html::submitButton($lang->convert->jira->next) . html::backButton();?>
</div>
</form>
</div>
+1 -1
View File
@@ -197,7 +197,7 @@ class cron extends control
if($now > $cron['time'])
{
if(!$this->cron->changeStatusRunning($id, $cronInfo->lastTime)) continue;
if(!$this->cron->changeStatusRunning($id)) continue;
$parsedCrons[$id]['time'] = $cron['cron']->getNextRunDate();
/* Execution command. */
+4 -4
View File
@@ -22,8 +22,8 @@ $config->custom->requiredModules[35] = 'execution';
$config->custom->requiredModules[40] = 'task';
$config->custom->requiredModules[45] = 'build';
$config->custom->allFeatures = array('program', 'productRR', 'productUR', 'productLine', 'projectScrum', 'projectWaterfall', 'projectKanban', 'execution', 'qa', 'devops', 'kanban', 'doc', 'report', 'system', 'admin', 'vision');
$config->custom->dataFeatures = array('productUR', 'waterfall');
$config->custom->allFeatures = array('program', 'productRR', 'productUR', 'productLine', 'projectScrum', 'projectWaterfall', 'projectKanban', 'projectAgileplus', 'projectWaterfallplus', 'execution', 'qa', 'devops', 'kanban', 'doc', 'report', 'system', 'admin', 'vision');
$config->custom->dataFeatures = array('productUR', 'waterfall', 'waterfallplus');
$config->custom->scrumFeatures = array();
$config->custom->requiredModules[50] = 'bug';
@@ -43,8 +43,8 @@ $config->custom->fieldList['project']['create'] = 'budget,PM,desc';
$config->custom->fieldList['project']['edit'] = 'budget,PM,desc';
$config->custom->fieldList['product']['create'] = 'PO,QD,RD,type,desc';
$config->custom->fieldList['product']['edit'] = 'PO,QD,RD,type,desc,status';
$config->custom->fieldList['story']['create'] = 'module,plan,source,pri,estimate,keywords,spec';
$config->custom->fieldList['story']['change'] = 'comment,spec';
$config->custom->fieldList['story']['create'] = 'module,plan,source,pri,estimate,keywords,spec,verify';
$config->custom->fieldList['story']['change'] = 'comment,spec,verify';
$config->custom->fieldList['story']['close'] = 'comment';
$config->custom->fieldList['story']['review'] = 'reviewedDate,comment';
$config->custom->fieldList['productplan'] = 'begin,end,desc';
+19
View File
@@ -862,6 +862,25 @@ class custom extends control
$this->display();
}
/**
* Set stage percent.
*
* @access public
* @return void
*/
public function percent()
{
if($_POST)
{
$this->loadModel('setting')->setItem('system.common.setPercent', $this->post->percent);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload'));
}
$this->view->title = $this->lang->stage->percent;
$this->display();
}
/**
* Set hours and weekend
*
+3
View File
@@ -0,0 +1,3 @@
.table-form>tbody>tr>th.c-setPercent {width: 135px;}
#readOnlyOfPercent {font-size: 13px; color: #5e626d; display: flex; width: 200%;}
#readOnlyOfPercent i {font-size: 14px; color: #0075ff; margin-right: 3px;}
+32 -26
View File
@@ -8,9 +8,9 @@ $lang->custom->set = 'Customize';
$lang->custom->restore = 'Reset to Default';
$lang->custom->key = 'Key';
$lang->custom->value = 'Value';
$lang->custom->flow = 'Concept';
$lang->custom->working = 'WorkStyle';
$lang->custom->select = 'Select Concept';
$lang->custom->hours = 'Hours';
$lang->custom->branch = 'Multi Branch';
$lang->custom->owner = 'Owner';
$lang->custom->module = 'Module';
@@ -59,6 +59,8 @@ $lang->custom->executionCommon = 'Execution';
$lang->custom->selectDefaultProgram = 'Please select default program';
$lang->custom->defaultProgram = 'Default program';
$lang->custom->modeManagement = 'Mode Management';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "Enable or Disable {$lang->stage->percent}";
$lang->custom->unitList['efficiency'] = 'Working Hours/';
$lang->custom->unitList['manhour'] = 'Man-hour/';
@@ -188,7 +190,7 @@ $lang->custom->notice->noClosedBlock = 'You have no blocks that are closed
$lang->custom->notice->required = 'The selected field is required.';
$lang->custom->notice->conceptResult = 'According to your preference, <b> %s-%s </b> is set for you. Use <b>%s</b> + <b> %s</b>。';
$lang->custom->notice->conceptPath = 'Go to Admin -> Custom -> Concept to set it.';
$lang->custom->notice->readOnlyOfProduct = 'If Change Forbidden, any change on stories, bugs, cases, efforts, releases and plans of the closed product is also forbidden.';
$lang->custom->notice->readOnlyOfProduct = 'If Change Forbidden, any change on stories, bugs, cases, efforts, releases, plans and builds of the closed product is also forbidden.';
$lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on tasks, builds, efforts and stories of the closed {$lang->executionCommon} is also forbidden.";
$lang->custom->notice->readOnlyOfKanban = "If Change Forbidden, any change on kanban card and related operations of {$lang->custom->kanban} is also forbidden.";
$lang->custom->notice->URSREmpty = 'Custom requirement name can not be empty!';
@@ -199,6 +201,7 @@ $lang->custom->notice->storyReviewTip = 'After selecting by individual, pos
$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.';
$lang->custom->notice->repeatKey = 'Repeat Key %s';
$lang->custom->notice->readOnlyOfCode = 'A code is a management term that exists for secrecy or as an antonym. When code management is enabled, the code information of product, project, and execution in the system will be displayed in the creation, editing, detail, and list pages.';
$lang->custom->notice->readOnlyOfPercent = 'The "Workload Ratio" is used to divide the workload of a project into different stages. The sum of the percentages of the same level stages cannot exceed 100%. After enabling the "Workload Ratio", users have to fill in the ratio fields when setting up the stages in the Waterfall project and Waterfall Plus project management models.';
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Homepage. Do you want to go to Product Homepage?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Homepage. Do you want to go to Project Homepage?";
@@ -252,31 +255,34 @@ $lang->custom->modeList['ALM'] = 'ALM Mode';
$lang->custom->modeIntroductionList['light'] = 'Provides the core function of project management, suitable for small R&D teams';
$lang->custom->modeIntroductionList['ALM'] = 'The concept is more complete and rigorous, and the function is more abundant. It is suitable for medium and large R&D teams';
$lang->custom->features['program'] = 'Program';
$lang->custom->features['productRR'] = 'Product - R&D Requirements';
$lang->custom->features['productUR'] = 'Product - User Requirements';
$lang->custom->features['productLine'] = 'Product - Product Line';
$lang->custom->features['projectScrum'] = 'Project - Scrum Model';
$lang->custom->features['projectWaterfall'] = 'Project - Waterfall Model';
$lang->custom->features['projectKanban'] = 'Project - Kanban Model';
$lang->custom->features['execution'] = 'Execution';
$lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = 'Statistics';
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
$lang->custom->features['ops'] = 'Deploy';
$lang->custom->features['feedback'] = 'Feedback';
$lang->custom->features['traincourse'] = 'Academy';
$lang->custom->features['workflow'] = 'Workflow';
$lang->custom->features['admin'] = 'Admin';
$lang->custom->features['vision'] = 'Full Feature Interface, Operation Management Interface';
$lang->custom->features['program'] = 'Program';
$lang->custom->features['productRR'] = $lang->productCommon . ' - R&D Requirements';
$lang->custom->features['productUR'] = $lang->productCommon . ' - User Requirements';
$lang->custom->features['productLine'] = $lang->productCommon . ' - Product Line';
$lang->custom->features['projectScrum'] = $lang->projectCommon . ' - Scrum Model';
$lang->custom->features['projectWaterfall'] = $lang->projectCommon . ' - Waterfall Model';
$lang->custom->features['projectKanban'] = $lang->projectCommon . ' - Kanban Model';
$lang->custom->features['projectAgileplus'] = $lang->projectCommon . ' - Agile + Model';
$lang->custom->features['projectWaterfallplus'] = $lang->projectCommon . ' - Waterfall + Model';
$lang->custom->features['execution'] = 'Execution';
$lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
$lang->custom->features['ops'] = 'Deploy';
$lang->custom->features['feedback'] = 'Feedback';
$lang->custom->features['traincourse'] = 'Academy';
$lang->custom->features['workflow'] = 'Workflow';
$lang->custom->features['admin'] = 'Admin';
$lang->custom->features['vision'] = 'Full Feature Interface, Operation Management Interface';
$lang->custom->needClosedFunctions['waterfall'] = 'Waterfall';
$lang->custom->needClosedFunctions['URStory'] = 'User Story';
$lang->custom->needClosedFunctions['waterfall'] = 'Waterfall';
$lang->custom->needClosedFunctions['waterfallplus'] = 'Waterfall +';
$lang->custom->needClosedFunctions['URStory'] = 'User Story';
if($config->edition == 'max') $lang->custom->needClosedFunctions['assetLib'] = 'Assetlib';
$lang->custom->scoreStatus[1] = 'On';
+32 -26
View File
@@ -8,9 +8,9 @@ $lang->custom->set = 'Customize';
$lang->custom->restore = 'Reset';
$lang->custom->key = 'Key';
$lang->custom->value = 'Value';
$lang->custom->flow = 'Concept';
$lang->custom->working = 'Mode';
$lang->custom->select = 'Select Concept';
$lang->custom->hours = 'Hours';
$lang->custom->branch = 'Multi-Branch';
$lang->custom->owner = 'Owner';
$lang->custom->module = 'Module';
@@ -59,6 +59,8 @@ $lang->custom->executionCommon = 'Execution';
$lang->custom->selectDefaultProgram = 'Please select default program';
$lang->custom->defaultProgram = 'Default program';
$lang->custom->modeManagement = 'Mode Management';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "Enable or Disable {$lang->stage->percent}";
$lang->custom->unitList['efficiency'] = 'Working Hours/';
$lang->custom->unitList['manhour'] = 'Man-hour/';
@@ -188,7 +190,7 @@ $lang->custom->notice->noClosedBlock = 'You have no blocks that are closed
$lang->custom->notice->required = 'The selected field is required.';
$lang->custom->notice->conceptResult = 'According to your preference, <b> %s-%s </b> is set for you. Use <b>%s</b> + <b> %s</b>.';
$lang->custom->notice->conceptPath = 'Go to Admin -> Custom -> Concept to set it.';
$lang->custom->notice->readOnlyOfProduct = 'If Change Forbidden, any change on stories, bugs, cases, efforts, releases and plans of the closed product is also forbidden.';
$lang->custom->notice->readOnlyOfProduct = 'If Change Forbidden, any change on stories, bugs, cases, efforts, releases, plans and builds of the closed product is also forbidden.';
$lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on tasks, builds, efforts and stories of the closed {$lang->executionCommon} is also forbidden.";
$lang->custom->notice->readOnlyOfKanban = "If Change Forbidden, any change on kanban card and related operations of {$lang->custom->kanban} is also forbidden.";
$lang->custom->notice->URSREmpty = 'Custom requirement name can not be empty!';
@@ -199,6 +201,7 @@ $lang->custom->notice->storyReviewTip = 'After selecting by individual, pos
$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.';
$lang->custom->notice->repeatKey = 'Repeat Key %s';
$lang->custom->notice->readOnlyOfCode = 'A code is a management term that exists for secrecy or as an antonym. When code management is enabled, the code information of product, project, and execution in the system will be displayed in the creation, editing, detail, and list pages.';
$lang->custom->notice->readOnlyOfPercent = 'The "Workload Ratio" is used to divide the workload of a project into different stages. The sum of the percentages of the same level stages cannot exceed 100%. After enabling the "Workload Ratio", users have to fill in the ratio fields when setting up the stages in the Waterfall project and Waterfall Plus project management models.';
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Home. Do you want to go to Product Home?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Home. Do you want to go to Project Home?";
@@ -252,31 +255,34 @@ $lang->custom->modeList['ALM'] = 'ALM Mode';
$lang->custom->modeIntroductionList['light'] = 'Provides the core function of project management, suitable for small R&D teams';
$lang->custom->modeIntroductionList['ALM'] = 'The concept is more complete and rigorous, and the function is more abundant. It is suitable for medium and large R&D teams';
$lang->custom->features['program'] = 'Program';
$lang->custom->features['productRR'] = 'Product - R&D Requirements';
$lang->custom->features['productUR'] = 'Product - User Requirements';
$lang->custom->features['productLine'] = 'Product - Product Line';
$lang->custom->features['projectScrum'] = 'Project - Scrum Model';
$lang->custom->features['projectWaterfall'] = 'Project - Waterfall Model';
$lang->custom->features['projectKanban'] = 'Project - Kanban Model';
$lang->custom->features['execution'] = 'Execution';
$lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = 'Statistics';
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
$lang->custom->features['ops'] = 'Deploy';
$lang->custom->features['feedback'] = 'Feedback';
$lang->custom->features['traincourse'] = 'Academy';
$lang->custom->features['workflow'] = 'Workflow';
$lang->custom->features['admin'] = 'Admin';
$lang->custom->features['vision'] = 'Full Feature Interface, Operation Management Interface';
$lang->custom->features['program'] = 'Program';
$lang->custom->features['productRR'] = $lang->productCommon . ' - R&D Requirements';
$lang->custom->features['productUR'] = $lang->productCommon . ' - User Requirements';
$lang->custom->features['productLine'] = $lang->productCommon . ' - Product Line';
$lang->custom->features['projectScrum'] = $lang->projectCommon . ' - Scrum Model';
$lang->custom->features['projectWaterfall'] = $lang->projectCommon . ' - Waterfall Model';
$lang->custom->features['projectKanban'] = $lang->projectCommon . ' - Kanban Model';
$lang->custom->features['projectAgileplus'] = $lang->projectCommon . ' - Agile + Model';
$lang->custom->features['projectWaterfallplus'] = $lang->projectCommon . ' - Waterfall + Model';
$lang->custom->features['execution'] = 'Execution';
$lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
$lang->custom->features['ops'] = 'Deploy';
$lang->custom->features['feedback'] = 'Feedback';
$lang->custom->features['traincourse'] = 'Academy';
$lang->custom->features['workflow'] = 'Workflow';
$lang->custom->features['admin'] = 'Admin';
$lang->custom->features['vision'] = 'Full Feature Interface, Operation Management Interface';
$lang->custom->needClosedFunctions['waterfall'] = 'Waterfall';
$lang->custom->needClosedFunctions['URStory'] = 'User Story';
$lang->custom->needClosedFunctions['waterfall'] = 'Waterfall';
$lang->custom->needClosedFunctions['waterfallplus'] = 'Waterfall +';
$lang->custom->needClosedFunctions['URStory'] = 'User Story';
if($config->edition == 'max') $lang->custom->needClosedFunctions['assetLib'] = 'Assetlib';
$lang->custom->scoreStatus[1] = 'On';
+32 -26
View File
@@ -8,9 +8,9 @@ $lang->custom->set = 'Personnaliser';
$lang->custom->restore = 'Réinitialiser';
$lang->custom->key = 'Clé';
$lang->custom->value = 'Valeur';
$lang->custom->flow = 'Concept';
$lang->custom->working = 'Mode';
$lang->custom->select = 'Choix du Concept';
$lang->custom->hours = 'Hours';
$lang->custom->branch = 'Multi-Branches';
$lang->custom->owner = 'Propriétaire';
$lang->custom->module = 'Module';
@@ -59,6 +59,8 @@ $lang->custom->executionCommon = 'Execution';
$lang->custom->selectDefaultProgram = 'Please select default program';
$lang->custom->defaultProgram = 'Default program';
$lang->custom->modeManagement = 'Mode Management';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "Enable or Disable {$lang->stage->percent}";
$lang->custom->unitList['efficiency'] = 'Working Hours/';
$lang->custom->unitList['manhour'] = 'Man-hour/';
@@ -188,7 +190,7 @@ $lang->custom->notice->noClosedBlock = "Vous n'avez aucun bloc fermé déf
$lang->custom->notice->required = 'Le champ sélectionné est obligatoire.';
$lang->custom->notice->conceptResult = 'Selon votre préférence, <b> %s-%s </b> peut être fixé pour vous. Utilisez <b>%s</b> + <b> %s</b>。';
$lang->custom->notice->conceptPath = 'Allez à Admin -> Custom -> Concept pour le paramétrer.';
$lang->custom->notice->readOnlyOfProduct = 'If Change Forbidden, any change on stories, bugs, cases, efforts, releases and plans of the closed product is also forbidden.';
$lang->custom->notice->readOnlyOfProduct = 'If Change Forbidden, any change on stories, bugs, cases, efforts, releases, plans and builds of the closed product is also forbidden.';
$lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on tasks, builds, efforts and stories of the closed {$lang->executionCommon} is also forbidden.";
$lang->custom->notice->readOnlyOfKanban = "If Change Forbidden, any change on kanban card and related operations of {$lang->custom->kanban} is also forbidden.";
$lang->custom->notice->URSREmpty = 'Custom requirement name can not be empty!';
@@ -199,6 +201,7 @@ $lang->custom->notice->storyReviewTip = 'After selecting by individual, pos
$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.';
$lang->custom->notice->repeatKey = 'Repeat Key %s';
$lang->custom->notice->readOnlyOfCode = "Le code est un terme de gestion utilisé pour la confidentialité ou comme alias. Lorsque la gestion du code est activée, le produit, le projet et l'exécution dans le système afficheront les informations de code sur les pages de création, de modification, de détails et de liste.";
$lang->custom->notice->readOnlyOfPercent = 'The "Workload Ratio" is used to divide the workload of a project into different stages. The sum of the percentages of the same level stages cannot exceed 100%. After enabling the "Workload Ratio", users have to fill in the ratio fields when setting up the stages in the Waterfall project and Waterfall Plus project management models.';
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ possède une page d'accueil. Voulez-vous consulter la page d'accueil du produit ?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ possède une page d'accueil. Voulez-vous consulter la page d'accueil du produit ?";
@@ -252,31 +255,34 @@ $lang->custom->modeList['ALM'] = 'ALM Mode';
$lang->custom->modeIntroductionList['light'] = 'Provides the core function of project management, suitable for small R&D teams';
$lang->custom->modeIntroductionList['ALM'] = 'The concept is more complete and rigorous, and the function is more abundant. It is suitable for medium and large R&D teams';
$lang->custom->features['program'] = 'Program';
$lang->custom->features['productRR'] = 'Product - R&D Requirements';
$lang->custom->features['productUR'] = 'Product - User Requirements';
$lang->custom->features['productLine'] = 'Product - Product Line';
$lang->custom->features['projectScrum'] = 'Project - Scrum Model';
$lang->custom->features['projectWaterfall'] = 'Project - Waterfall Model';
$lang->custom->features['projectKanban'] = 'Project - Kanban Model';
$lang->custom->features['execution'] = 'Execution';
$lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = 'Statistics';
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
$lang->custom->features['ops'] = 'Deploy';
$lang->custom->features['feedback'] = 'Feedback';
$lang->custom->features['traincourse'] = 'Academy';
$lang->custom->features['workflow'] = 'Workflow';
$lang->custom->features['admin'] = 'Admin';
$lang->custom->features['vision'] = 'Full Feature Interface, Operation Management Interface';
$lang->custom->features['program'] = 'Program';
$lang->custom->features['productRR'] = $lang->productCommon . ' - R&D Requirements';
$lang->custom->features['productUR'] = $lang->productCommon . ' - User Requirements';
$lang->custom->features['productLine'] = $lang->productCommon . ' - Product Line';
$lang->custom->features['projectScrum'] = $lang->projectCommon . ' - Scrum Model';
$lang->custom->features['projectWaterfall'] = $lang->projectCommon . ' - Waterfall Model';
$lang->custom->features['projectKanban'] = $lang->projectCommon . ' - Kanban Model';
$lang->custom->features['projectAgileplus'] = $lang->projectCommon . ' - Agile + Model';
$lang->custom->features['projectWaterfallplus'] = $lang->projectCommon . ' - Waterfall + Model';
$lang->custom->features['execution'] = 'Execution';
$lang->custom->features['qa'] = 'QA';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = 'Kanban';
$lang->custom->features['doc'] = 'Doc';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = 'System';
$lang->custom->features['assetlib'] = 'Asset Lib';
$lang->custom->features['oa'] = 'Attend';
$lang->custom->features['ops'] = 'Deploy';
$lang->custom->features['feedback'] = 'Feedback';
$lang->custom->features['traincourse'] = 'Academy';
$lang->custom->features['workflow'] = 'Workflow';
$lang->custom->features['admin'] = 'Admin';
$lang->custom->features['vision'] = 'Full Feature Interface, Operation Management Interface';
$lang->custom->needClosedFunctions['waterfall'] = 'Waterfall';
$lang->custom->needClosedFunctions['URStory'] = 'User Story';
$lang->custom->needClosedFunctions['waterfall'] = 'Waterfall';
$lang->custom->needClosedFunctions['waterfallplus'] = 'Waterfall +';
$lang->custom->needClosedFunctions['URStory'] = 'User Story';
if($config->edition == 'max') $lang->custom->needClosedFunctions['assetLib'] = 'Assetlib';
$lang->custom->scoreStatus[1] = 'On';
+32 -26
View File
@@ -8,8 +8,8 @@ $lang->custom->set = '自定义配置';
$lang->custom->restore = '恢复默认';
$lang->custom->key = '键';
$lang->custom->value = '值';
$lang->custom->flow = '流程设置';
$lang->custom->working = '工作方式';
$lang->custom->hours = '工时';
$lang->custom->select = '请选择流程:';
$lang->custom->branch = '多分支';
$lang->custom->owner = '所有者';
@@ -59,6 +59,8 @@ $lang->custom->executionCommon = '执行';
$lang->custom->selectDefaultProgram = '请选择一个默认项目集';
$lang->custom->defaultProgram = '默认项目集';
$lang->custom->modeManagement = '模式管理';
$lang->custom->percent = $lang->stage->percent;
$lang->custom->setPercent = "是否启用{$lang->stage->percent}";
$lang->custom->unitList['efficiency'] = '工时/';
$lang->custom->unitList['manhour'] = '人时/';
@@ -188,7 +190,7 @@ $lang->custom->notice->noClosedBlock = '没有永久关闭的区块';
$lang->custom->notice->required = '页面提交时,选中的字段必填';
$lang->custom->notice->conceptResult = '我们已经根据您的选择为您设置了<b> %s-%s </b>模式,使用<b>%s</b> + <b> %s</b>。';
$lang->custom->notice->conceptPath = '您可以在:后台 -> 自定义 -> 流程页面修改。';
$lang->custom->notice->readOnlyOfProduct = '禁止修改后,已关闭' . $lang->productCommon . '下的' . $lang->SRCommon . '、Bug、用例、日志、发布、计划都禁止修改。';
$lang->custom->notice->readOnlyOfProduct = '禁止修改后,已关闭' . $lang->productCommon . '下的' . $lang->SRCommon . '、Bug、用例、日志、发布、计划、版本都禁止修改。';
$lang->custom->notice->readOnlyOfExecution = "禁止修改后,已关闭{$lang->custom->executionCommon}下的任务、版本、日志以及关联需求都禁止修改。";
$lang->custom->notice->readOnlyOfKanban = "禁止修改后,已关闭{$lang->custom->kanban}下的卡片以及相关设置都禁止修改。";
$lang->custom->notice->URSREmpty = '自定义需求名称不能为空!';
@@ -199,6 +201,7 @@ $lang->custom->notice->storyReviewTip = '按人员、职位、部门勾选
$lang->custom->notice->selectAllTip = '勾选所有人员后,会清空并置灰评审人员,同时隐藏职位、部门。';
$lang->custom->notice->repeatKey = '%s键重复';
$lang->custom->notice->readOnlyOfCode = '代号是一种管理话术,主要便于保密或作为别名存在。启用代号管理后,系统中的产品、项目、执行在创建、编辑、详情、列表等页面均会展示代号信息。';
$lang->custom->notice->readOnlyOfPercent = '工作量占比用于划分项目中存在多个阶段时的工作量的占比,同一级阶段的百分比之和最高为100%。启用工作量占比后,系统中的瀑布项目和融合瀑布项目模型中设置阶段时需要维护阶段的工作量占比。';
$lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主页视图,是否默认进入产品主页?";
$lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?";
@@ -252,31 +255,34 @@ $lang->custom->modeList['ALM'] = '全生命周期管理模式';
$lang->custom->modeIntroductionList['light'] = '提供了项目管理的核心功能,适用于小型研发团队';
$lang->custom->modeIntroductionList['ALM'] = '概念更加完整、严谨,功能更加丰富,适用于中大型研发团队';
$lang->custom->features['program'] = '项目集';
$lang->custom->features['productRR'] = '产品-研发需求';
$lang->custom->features['productUR'] = '产品-用户需求';
$lang->custom->features['productLine'] = '产品-产品线';
$lang->custom->features['projectScrum'] = '项目-敏捷模型';
$lang->custom->features['projectWaterfall'] = '项目-瀑布模型';
$lang->custom->features['projectKanban'] = '项目-看板模型';
$lang->custom->features['execution'] = '执行';
$lang->custom->features['qa'] = '测试';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = '看板';
$lang->custom->features['doc'] = '文档';
$lang->custom->features['report'] = '统计';
$lang->custom->features['system'] = '组织';
$lang->custom->features['assetlib'] = '资产库';
$lang->custom->features['oa'] = '办公';
$lang->custom->features['ops'] = '运维';
$lang->custom->features['feedback'] = '反馈';
$lang->custom->features['traincourse'] = '学堂';
$lang->custom->features['workflow'] = '工作流';
$lang->custom->features['admin'] = '后台';
$lang->custom->features['vision'] = '研发综合界面、运营管理界面';
$lang->custom->features['program'] = '项目集';
$lang->custom->features['productRR'] = '产品-研发需求';
$lang->custom->features['productUR'] = '产品-用户需求';
$lang->custom->features['productLine'] = '产品-产品线';
$lang->custom->features['projectScrum'] = '项目-敏捷模型';
$lang->custom->features['projectWaterfall'] = '项目-瀑布模型';
$lang->custom->features['projectKanban'] = '项目-看板模型';
$lang->custom->features['projectAgileplus'] = '项目-融合敏捷模型';
$lang->custom->features['projectWaterfallplus'] = '项目-融合瀑布模型';
$lang->custom->features['execution'] = '执行';
$lang->custom->features['qa'] = '测试';
$lang->custom->features['devops'] = 'DevOps';
$lang->custom->features['kanban'] = '看板';
$lang->custom->features['doc'] = '文档';
$lang->custom->features['report'] = $lang->report->common;
$lang->custom->features['system'] = '组织';
$lang->custom->features['assetlib'] = '资产库';
$lang->custom->features['oa'] = '办公';
$lang->custom->features['ops'] = '运维';
$lang->custom->features['feedback'] = '反馈';
$lang->custom->features['traincourse'] = '学堂';
$lang->custom->features['workflow'] = '工作流';
$lang->custom->features['admin'] = '后台';
$lang->custom->features['vision'] = '研发综合界面、运营管理界面';
$lang->custom->needClosedFunctions['waterfall'] = '瀑布项目';
$lang->custom->needClosedFunctions['URStory'] = '用户需求';
$lang->custom->needClosedFunctions['waterfall'] = '瀑布项目';
$lang->custom->needClosedFunctions['waterfallplus'] = '融合瀑布项目';
$lang->custom->needClosedFunctions['URStory'] = '用户需求';
if($config->edition == 'max') $lang->custom->needClosedFunctions['assetLib'] = '资产库';
$lang->custom->scoreStatus[1] = '开启';
+31 -7
View File
@@ -204,6 +204,9 @@ class customModel extends model
ksort($menuOrder);
foreach($menuOrder as $name)
{
/* If menu is removed, delete the menuOrder. */
if(!isset($allMenu->$name)) continue;
$item = new stdclass();
$item->name = $name;
$item->hidden = false;
@@ -840,7 +843,7 @@ class customModel extends model
if(!isset($disabledFeatures['scrum'])) $disabledFeatures['scrum'] = array();
$disabledFeatures['scrum'][] = $feature;
}
elseif($feature == 'waterfall')
elseif(in_array($feature, array('waterfall', 'waterfallplus')))
{
$disabledFeatures[] = 'project' . ucfirst($feature);
}
@@ -955,14 +958,21 @@ class customModel extends model
foreach($this->config->custom->dataFeatures as $feature)
{
$function = 'has' . ucfirst($feature) . 'Data';
if(!$this->$function()) $disabledFeatures .= "$feature,";
if(!$this->$function())
{
$disabledFeatures .= "$feature,";
if(strpos($feature, 'scrum') === 0) $disabledFeatures .= 'agileplus' . substr($feature, 5) . ',';
}
}
$disabledFeatures .= 'scrumMeasrecord,productTrack,productRoadmap';
$disabledFeatures .= 'scrumMeasrecord,agileplusMeasrecord,productTrack,productRoadmap';
}
$disabledFeatures = rtrim($disabledFeatures, ',');
$this->loadModel('setting')->setItem('system.common.disabledFeatures', $disabledFeatures);
$URAndSR = strpos(",$disabledFeatures,", ',productUR,') === false ? 1 : 0;
$this->setting->setItem('system.custom.URAndSR', $URAndSR);
$this->processMeasrecordCron();
}
@@ -988,6 +998,17 @@ class customModel extends model
return $this->dao->select('*')->from(TABLE_PROJECT)->where('model')->eq('waterfall')->andWhere('deleted')->eq('0')->count();
}
/**
* Check for waterfallplus project data.
*
* @access public
* @return int
*/
public function hasWaterfallplusData()
{
return $this->dao->select('*')->from(TABLE_PROJECT)->where('model')->eq('waterfallplus')->andWhere('deleted')->eq('0')->count();
}
/**
* Check for assetlib data.
*
@@ -1123,12 +1144,15 @@ class customModel extends model
$disabledFeatures = $this->setting->getItem('owner=system&module=common&section=&key=disabledFeatures');
$disabledFeatures = $disabledFeatures . ',' . $closedFeatures;
$hasWaterfall = strpos(",{$disabledFeatures},", ',waterfall,') === false;
$hasScrumMeasrecord = strpos(",{$disabledFeatures},", ',scrumMeasrecord,') === false;
$hasWaterfallMeasrecord = (strpos(",{$disabledFeatures},", ',waterfallMeasrecord,') === false and $hasWaterfall);
$hasWaterfall = strpos(",{$disabledFeatures},", ',waterfall,') === false;
$hasWaterfallPlus = strpos(",{$disabledFeatures},", ',waterfallplus,') === false;
$hasScrumMeasrecord = strpos(",{$disabledFeatures},", ',scrumMeasrecord,') === false;
$hasAgilePlusMeasrecord = strpos(",{$disabledFeatures},", ',agileMeasrecord,') === false;
$hasWaterfallMeasrecord = (strpos(",{$disabledFeatures},", ',waterfallMeasrecord,') === false and $hasWaterfall);
$hasWaterfallPlusMeasrecord = (strpos(",{$disabledFeatures},", ',waterfallplusMeasrecord,') === false and $hasWaterfallPlus);
$cronStatus = 'normal';
if(!$hasScrumMeasrecord and !$hasWaterfallMeasrecord) $cronStatus = 'stop';
if(!$hasScrumMeasrecord and !$hasAgilePlusMeasrecord and !$hasWaterfallMeasrecord and $hasWaterfallPlusMeasrecord) $cronStatus = 'stop';
$this->loadModel('cron');
$cron = $this->dao->select('id,status')->from(TABLE_CRON)->where('command')->like('%methodName=initCrontabQueue')->fetch();
+1 -1
View File
@@ -16,7 +16,7 @@
<tr>
<th class='c-setCode'><?php echo $lang->custom->setCode;?></th>
<td class='c-code text-left'>
<?php $checkedKey = isset($config->setCode) ? $config->setCode : 1;?>
<?php $checkedKey = isset($config->setCode) ? $config->setCode : 0;?>
<?php foreach($lang->custom->conceptOptions->URAndSR as $key => $value):?>
<label class="radio-inline"><input type="radio" name="code" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="code<?php echo $key;?>"><?php echo $value;?></label>
<?php endforeach;?>
+1 -1
View File
@@ -17,7 +17,7 @@
<div class='nav list-group tab-menu'>
<a href="#hoursContent" data-toggle="tab" class="hours <?php if($type == 'hours') echo 'active'?>"><?php echo $lang->custom->setHours;?></a>
<a href="#weekendContent" data-toggle="tab" class="weekend <?php if($type == 'weekend') echo 'active'?>"><?php echo $lang->custom->setWeekend;?></a>
<?php echo html::a($this->createLink('holiday', 'browse'), $lang->custom->setHoliday);?>
<?php if(common::hasPriv('holiday', 'browse')) echo html::a($this->createLink('holiday', 'browse'), $lang->custom->setHoliday);?>
</div>
</div>
</div>
+5 -5
View File
@@ -36,19 +36,19 @@
<td class='text-center'><?php echo $lang->custom->modeIntroductionList['ALM'];?></td>
</tr>
<?php foreach($disabledFeatures as $feature):?>
<?php if(is_array($feature) && empty($disabledScrumFeatures)) continue;?>
<?php if(is_array($feature) and empty($disabledScrumFeatures)) continue;?>
<tr class='text-center'>
<td class='text-left'><?php echo (is_array($feature) && !empty($disabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
<td><i class='icon text-red icon-close'></i></td>
<td class='text-left'><?php echo (is_array($feature) and !empty($disabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
<td><i class='icon text-red icon-ban-circle'></i></td>
<td><i class='icon text-success icon-check'></i></td>
</tr>
<?php endforeach;?>
<?php foreach($config->custom->allFeatures as $feature):?>
<?php if(in_array($feature, $disabledFeatures)) continue;?>
<?php if($feature == 'scrumDetail' && empty($enabledScrumFeatures)) continue;?>
<?php if($feature == 'scrumDetail' and empty($enabledScrumFeatures)) continue;?>
<tr class='text-center'>
<td class='text-left'><?php echo ($feature == 'scrumDetail' && !empty($enabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $enabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
<td class='text-left'><?php echo ($feature == 'scrumDetail' and !empty($enabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $enabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
<td><i class='icon text-success icon-check'></i></td>
<td><i class='icon text-success icon-check'></i></td>
</tr>
+42
View File
@@ -0,0 +1,42 @@
<?php
/**
* The percent view file of custom module of ZenTaoPMS.
* @copyright Copyright 2009-2022 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Shujie Tian <tianshujie@cnezsoft.com>
* @package custom
* @version $Id$
* @link https://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<div id='mainContent' class='main-content'>
<form class="load-indicator main-form form-ajax" method='post'>
<table class='table table-form'>
<tr>
<th class='c-setPercent'><?php echo $lang->custom->setPercent;?></th>
<td class='c-percent text-left'>
<?php $checkedKey = isset($config->setPercent) ? $config->setPercent : 0;?>
<?php foreach($lang->custom->conceptOptions->URAndSR as $key => $value):?>
<label class="radio-inline"><input type="radio" name="percent" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="percent<?php echo $key;?>"><?php echo $value;?></label>
<?php endforeach;?>
</td>
<td></td>
</tr>
<tr>
<th></th>
<td colspan="2" id="readOnlyOfPercent">
<div class="inline-block"><i class="icon-exclamation-sign"></i>&nbsp;</div>
<div class="inline-block"><?php echo $lang->custom->notice->readOnlyOfPercent;?></div>
</td>
</tr>
<tr>
<th></th>
<td class='form-actions'>
<?php echo html::submitButton();?>
</td>
</tr>
</table>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+22 -7
View File
@@ -71,6 +71,9 @@ class design extends control
{
$productID = $this->commonAction($projectID, $productID);
$project = $this->loadModel('project')->getByID($projectID);
$typeList = $project->model == 'waterfall' ? $this->lang->design->typeList : $this->lang->design->plusTypeList;
/* Save session for design list and process product id. */
$this->session->set('designList', $this->app->getURI(true), 'project');
$this->session->set('reviewList', $this->app->getURI(true), 'project');
@@ -80,6 +83,7 @@ class design extends control
$productIdList = $productID ? $productID : array_keys($products);
$stories = $this->loadModel('story')->getProductStoryPairs($productIdList, 'all', 0, 'active', 'id_desc', 0, 'full', 'story', false);
$this->config->design->search['params']['story']['values'] = $stories;
$this->config->design->search['params']['type']['values'] = $typeList;
$queryID = ($type == 'bySearch') ? (int)$param : 0;
$actionURL = $this->createLink('design', 'browse', "projectID=$projectID&productID=$productID&type=bySearch&queryID=myQueryID");
@@ -120,7 +124,6 @@ class design extends control
$pager = pager::init(0, $recPerPage, $pageID);
$designs = $this->design->getList($projectID, $productID, $type, $queryID, $orderBy, $pager);
$project = $this->loadModel('project')->getByID($projectID);
$this->view->hiddenProduct = $project->hasProduct ? false : true;
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->browse;
@@ -134,6 +137,7 @@ class design extends control
$this->view->projectID = $projectID;
$this->view->pager = $pager;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->typeList = $typeList;
$this->display();
}
@@ -173,6 +177,8 @@ class design extends control
$products = $this->product->getProductPairsByProject($projectID);
$productIdList = $productID ? $productID : array_keys($products);
$project = $this->loadModel('project')->getByID($projectID);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->create;
$this->view->position[] = $this->lang->design->create;
@@ -181,7 +187,7 @@ class design extends control
$this->view->productID = $productID;
$this->view->projectID = $projectID;
$this->view->type = $type;
$this->view->project = $this->loadModel('project')->getByID($projectID);
$this->view->typeList = $project->model == 'waterfall' ? $this->lang->design->typeList : $this->lang->design->plusTypeList;
$this->display();
}
@@ -220,12 +226,15 @@ class design extends control
$products = $this->product->getProductPairsByProject($projectID);
$productIdList = $productID ? $productID : array_keys($products);
$project = $this->loadModel('project')->getByID($projectID);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->batchCreate;
$this->view->position[] = $this->lang->design->batchCreate;
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productIdList);
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->type = $type;
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productIdList);
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->type = $type;
$this->view->typeList = $project->model == 'waterfall' ? $this->lang->design->typeList : $this->lang->design->plusTypeList;
$this->display();
}
@@ -248,6 +257,8 @@ class design extends control
$products = $this->product->getProductPairsByProject($design->project);
$productIdList = $design->product ? $design->product : array_keys($products);
$project = $this->loadModel('project')->getByID($design->project);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->view;
$this->view->position[] = $this->lang->design->view;
@@ -256,7 +267,8 @@ class design extends control
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->actions = $this->loadModel('action')->getList('design', $design->id);
$this->view->repos = $this->loadModel('repo')->getRepoPairs('project', $design->project);
$this->view->project = $this->loadModel('project')->getByID($design->project);
$this->view->project = $project;
$this->view->typeList = $project->model == 'waterfall' ? $this->lang->design->typeList : $this->lang->design->plusTypeList;
$this->display();
}
@@ -300,13 +312,16 @@ class design extends control
$products = $this->product->getProductPairsByProject($design->project);
$productIdList = $design->product ? $design->product : array_keys($products);
$project = $this->loadModel('project')->getByID($design->project);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->edit;
$this->view->position[] = $this->lang->design->edit;
$this->view->design = $design;
$this->view->project = $this->loadModel('project')->getByID($design->project);
$this->view->project = $project;
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productIdList);
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->typeList = $project->model == 'waterfall' ? $this->lang->design->typeList : $this->lang->design->plusTypeList;
$this->display();
}
+2
View File
@@ -65,6 +65,8 @@ $lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->plusTypeList = $lang->design->typeList;
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';
+2
View File
@@ -65,6 +65,8 @@ $lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->plusTypeList = $lang->design->typeList;
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';
+2
View File
@@ -65,6 +65,8 @@ $lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->plusTypeList = $lang->design->typeList;
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';

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