Merge branch 'master' into 'sprint/174_xieqiyu_45080'

# Conflicts:
#   module/story/control.php
#   module/story/view/header.html.php
#   module/testcase/control.php
This commit is contained in:
李玉春
2021-11-30 07:44:47 +00:00
375 changed files with 16559 additions and 3742 deletions
+48 -39
View File
@@ -170,6 +170,7 @@ define('TABLE_USERTPL', '`' . $config->db->prefix . 'usertpl`');
define('TABLE_PRODUCT', '`' . $config->db->prefix . 'product`');
define('TABLE_BRANCH', '`' . $config->db->prefix . 'branch`');
define('TABLE_EXPECT', '`' . $config->db->prefix . 'expect`');
define('TABLE_STAGE', '`' . $config->db->prefix . 'stage`');
define('TABLE_STAKEHOLDER', '`' . $config->db->prefix . 'stakeholder`');
define('TABLE_STORY', '`' . $config->db->prefix . 'story`');
define('TABLE_STORYSPEC', '`' . $config->db->prefix . 'storyspec`');
@@ -195,6 +196,8 @@ define('TABLE_BURN', '`' . $config->db->prefix . 'burn`');
define('TABLE_BUILD', '`' . $config->db->prefix . 'build`');
define('TABLE_ACL', '`' . $config->db->prefix . 'acl`');
define('TABLE_DESIGN', '`' . $config->db->prefix . 'design`');
define('TABLE_DESIGNSPEC', '`' . $config->db->prefix . 'designspec`');
define('TABLE_DOCLIB', '`' . $config->db->prefix . 'doclib`');
define('TABLE_DOC', '`' . $config->db->prefix . 'doc`');
define('TABLE_API', '`' . $config->db->prefix . 'api`');
@@ -206,6 +209,7 @@ define('TABLE_API_LIB_RELEASE', '`' . $config->db->prefix . 'api_lib_release`');
define('TABLE_MODULE', '`' . $config->db->prefix . 'module`');
define('TABLE_ACTION', '`' . $config->db->prefix . 'action`');
define('TABLE_FILE', '`' . $config->db->prefix . 'file`');
define('TABLE_HOLIDAY', '`' . $config->db->prefix . 'holiday`');
define('TABLE_HISTORY', '`' . $config->db->prefix . 'history`');
define('TABLE_EXTENSION', '`' . $config->db->prefix . 'extension`');
define('TABLE_CRON', '`' . $config->db->prefix . 'cron`');
@@ -216,6 +220,7 @@ define('TABLE_SUITECASE', '`' . $config->db->prefix . 'suitecase`');
define('TABLE_TESTREPORT', '`' . $config->db->prefix . 'testreport`');
define('TABLE_ENTRY', '`' . $config->db->prefix . 'entry`');
define('TABLE_WEEKLYREPORT', '`' . $config->db->prefix . 'weeklyreport`');
define('TABLE_WEBHOOK', '`' . $config->db->prefix . 'webhook`');
define('TABLE_LOG', '`' . $config->db->prefix . 'log`');
define('TABLE_SCORE', '`' . $config->db->prefix . 'score`');
@@ -226,53 +231,57 @@ define('TABLE_JOB', '`' . $config->db->prefix . 'job`');
define('TABLE_COMPILE', '`' . $config->db->prefix . 'compile`');
define('TABLE_MR', '`' . $config->db->prefix . 'mr`');
define('TABLE_REPO', '`' . $config->db->prefix . 'repo`');
define('TABLE_RELATION', '`' . $config->db->prefix . 'relation`');
define('TABLE_REPOHISTORY', '`' . $config->db->prefix . 'repohistory`');
define('TABLE_REPOFILES', '`' . $config->db->prefix . 'repofiles`');
define('TABLE_REPOBRANCH', '`' . $config->db->prefix . 'repobranch`');
define('TABLE_REPO', '`' . $config->db->prefix . 'repo`');
define('TABLE_RELATION', '`' . $config->db->prefix . 'relation`');
define('TABLE_REPOHISTORY', '`' . $config->db->prefix . 'repohistory`');
define('TABLE_REPOFILES', '`' . $config->db->prefix . 'repofiles`');
define('TABLE_REPOBRANCH', '`' . $config->db->prefix . 'repobranch`');
define('TABLE_KANBANLANE', '`' . $config->db->prefix . 'kanbanlane`');
define('TABLE_KANBANCOLUMN', '`' . $config->db->prefix . 'kanbancolumn`');
if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`');
if(!defined('TABLE_PROJECTSPEC')) define('TABLE_PROJECTSPEC', '`' . $config->db->prefix . 'projectspec`');
if(!defined('TABLE_SEARCHINDEX')) define('TABLE_SEARCHINDEX', $config->db->prefix . 'searchindex');
if(!defined('TABLE_SEARCHDICT')) define('TABLE_SEARCHDICT', $config->db->prefix . 'searchdict');
$config->objectTables['product'] = TABLE_PRODUCT;
$config->objectTables['productplan'] = TABLE_PRODUCTPLAN;
$config->objectTables['story'] = TABLE_STORY;
$config->objectTables['requirement'] = TABLE_STORY;
$config->objectTables['release'] = TABLE_RELEASE;
$config->objectTables['program'] = TABLE_PROJECT;
$config->objectTables['project'] = TABLE_PROJECT;
$config->objectTables['execution'] = TABLE_PROJECT;
$config->objectTables['task'] = TABLE_TASK;
$config->objectTables['build'] = TABLE_BUILD;
$config->objectTables['bug'] = TABLE_BUG;
$config->objectTables['case'] = TABLE_CASE;
$config->objectTables['testcase'] = TABLE_CASE;
$config->objectTables['testtask'] = TABLE_TESTTASK;
$config->objectTables['testsuite'] = TABLE_TESTSUITE;
$config->objectTables['testreport'] = TABLE_TESTREPORT;
$config->objectTables['user'] = TABLE_USER;
$config->objectTables['api'] = TABLE_API;
$config->objectTables['doc'] = TABLE_DOC;
$config->objectTables['doclib'] = TABLE_DOCLIB;
$config->objectTables['todo'] = TABLE_TODO;
$config->objectTables['custom'] = TABLE_LANG;
$config->objectTables['branch'] = TABLE_BRANCH;
$config->objectTables['module'] = TABLE_MODULE;
$config->objectTables['caselib'] = TABLE_TESTSUITE;
$config->objectTables['entry'] = TABLE_ENTRY;
$config->objectTables['webhook'] = TABLE_WEBHOOK;
$config->objectTables['stakeholder'] = TABLE_STAKEHOLDER;
$config->objectTables['job'] = TABLE_JOB;
$config->objectTables['team'] = TABLE_TEAM;
$config->objectTables['pipeline'] = TABLE_PIPELINE;
$config->objectTables['mr'] = TABLE_MR;
$config->objectTables['product'] = TABLE_PRODUCT;
$config->objectTables['productplan'] = TABLE_PRODUCTPLAN;
$config->objectTables['story'] = TABLE_STORY;
$config->objectTables['requirement'] = TABLE_STORY;
$config->objectTables['release'] = TABLE_RELEASE;
$config->objectTables['program'] = TABLE_PROJECT;
$config->objectTables['project'] = TABLE_PROJECT;
$config->objectTables['execution'] = TABLE_PROJECT;
$config->objectTables['task'] = TABLE_TASK;
$config->objectTables['build'] = TABLE_BUILD;
$config->objectTables['bug'] = TABLE_BUG;
$config->objectTables['case'] = TABLE_CASE;
$config->objectTables['testcase'] = TABLE_CASE;
$config->objectTables['testtask'] = TABLE_TESTTASK;
$config->objectTables['testsuite'] = TABLE_TESTSUITE;
$config->objectTables['testreport'] = TABLE_TESTREPORT;
$config->objectTables['user'] = TABLE_USER;
$config->objectTables['api'] = TABLE_API;
$config->objectTables['doc'] = TABLE_DOC;
$config->objectTables['doclib'] = TABLE_DOCLIB;
$config->objectTables['todo'] = TABLE_TODO;
$config->objectTables['custom'] = TABLE_LANG;
$config->objectTables['branch'] = TABLE_BRANCH;
$config->objectTables['module'] = TABLE_MODULE;
$config->objectTables['caselib'] = TABLE_TESTSUITE;
$config->objectTables['entry'] = TABLE_ENTRY;
$config->objectTables['webhook'] = TABLE_WEBHOOK;
$config->objectTables['stakeholder'] = TABLE_STAKEHOLDER;
$config->objectTables['job'] = TABLE_JOB;
$config->objectTables['team'] = TABLE_TEAM;
$config->objectTables['pipeline'] = TABLE_PIPELINE;
$config->objectTables['mr'] = TABLE_MR;
$config->objectTables['kanbancolumn'] = TABLE_KANBANCOLUMN;
$config->objectTables['kanbanlane'] = TABLE_KANBANLANE;
$config->newFeatures = array('introduction', 'tutorial', 'youngBlueTheme');
/* Program privs.*/
$config->programPriv = new stdclass();
$config->programPriv->scrum = array('product', 'story', 'productplan', 'release', 'projectrelease', 'project', 'task', 'build', 'qa', 'bug', 'testcase', 'testsuite', 'testreport', 'caselib', 'doc', 'report', 'repo', 'svn', 'git', 'search', 'tree', 'file', 'jenkins', 'gitlab', 'job', 'ci', 'branch');
$config->programPriv->waterfall = $config->programPriv->scrum + array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'milestone', 'design', 'issue', 'risk', 'auditplan', 'nc', 'cm', 'pssp');
$config->programPriv->scrum = array('projectstory', 'projectrelease', 'project', 'build', 'bug', 'testcase', 'testreport', 'caselib', 'doc', 'repo', 'meeting', 'stakeholder');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp'));
+137
View File
@@ -5,3 +5,140 @@ ALTER TABLE `zt_branch` ADD `createdDate` date NOT NULL AFTER `desc`;
ALTER TABLE `zt_branch` ADD `closedDate` date NOT NULL AFTER `createdDate`;
ALTER TABLE `zt_projectstory` ADD `branch` mediumint(8) NOT NULL AFTER `product`;
ALTER TABLE `zt_projectproduct` ADD PRIMARY KEY `project_product_branch` (`project`, `product`, `branch`), DROP INDEX `PRIMARY`;
-- DROP TABLE IF EXISTS `zt_kanbanlane`;
CREATE TABLE IF NOT EXISTS `zt_kanbanlane` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`execution` mediumint(8) NOT NULL DEFAULT '0',
`type` char(30) NOT NULL,
`groupby` char(30) NOT NULL,
`extra` char(30) NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`color` char(30) NOT NULL,
`order` smallint(6) NOT NULL DEFAULT '0',
`lastEditedTime` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_kanbancolumn`;
CREATE TABLE IF NOT EXISTS `zt_kanbancolumn` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`lane` mediumint(8) NOT NULL DEFAULT '0',
`parent` mediumint(8) NOT NULL DEFAULT '0',
`type` char(30) NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`color` char(30) NOT NULL,
`limit` smallint(6) NOT NULL DEFAULT '-1',
`order` mediumint(8) NOT NULL DEFAULT '0',
`cards` text NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_stage`;
CREATE TABLE IF NOT EXISTS `zt_stage` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`percent` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_design`;
CREATE TABLE IF NOT EXISTS `zt_design` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`project` varchar(255) NOT NULL,
`product` varchar(255) NOT NULL,
`commit` text NOT NULL,
`commitedBy` varchar(30) NOT NULL,
`execution` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`status` varchar(30) NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`assignedBy` varchar(30) NOT NULL,
`assignedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`story` char(30) NOT NULL,
`desc` text NOT NULL,
`version` smallint(6) NOT NULL,
`type` char(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_designspec`;
CREATE TABLE IF NOT EXISTS `zt_designspec` (
`design` mediumint(8) NOT NULL,
`version` smallint(6) NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`files` varchar(255) NOT NULL,
UNIQUE KEY `design` (`design`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_weeklyreport`;
CREATE TABLE IF NOT EXISTS `zt_weeklyreport`(
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`project` mediumint(8) unsigned NOT NULL,
`weekStart` date NOT NULL,
`pv` float(9,2) NOT NULL,
`ev` float(9,2) NOT NULL,
`ac` float(9,2) NOT NULL,
`sv` float(9,2) NOT NULL,
`cv` float(9,2) NOT NULL,
`staff` smallint(5) unsigned NOT NULL,
`progress` varchar(255) NOT NULL,
`workload` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `week` (`project`,`weekStart`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_holiday`;
CREATE TABLE IF NOT EXISTS `zt_holiday` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '',
`type` enum('holiday', 'working') NOT NULL DEFAULT 'holiday',
`desc` text NOT NULL,
`year` char(4) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
PRIMARY KEY (`id`),
KEY `year` (`year`),
KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
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');
INSERT INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) VALUES
('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');
ALTER TABLE `zt_bug`
ADD `feedbackBy` varchar(100) NOT NULL AFTER `activatedDate`,
ADD `notifyEmail` varchar(100) NOT NULL AFTER `feedbackBy`;
ALTER TABLE `zt_story`
ADD `feedbackBy` varchar(100) NOT NULL AFTER `version`,
ADD `notifyEmail` varchar(100) NOT NULL AFTER `feedbackBy`;
ALTER TABLE `zt_product` ADD `reviewer` varchar(255) NOT NULL AFTER `whitelist`;
+204 -86
View File
@@ -30,99 +30,94 @@ CREATE TABLE IF NOT EXISTS `zt_action` (
KEY `objectID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_api_lib_release`;
CREATE TABLE `zt_api_lib_release`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`desc` varchar(255) NOT NULL DEFAULT '',
`version` varchar(255) NOT NULL DEFAULT '',
`snap` mediumtext NOT NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
PRIMARY KEY (`id`)
CREATE TABLE `zt_api_lib_release` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`desc` varchar(255) NOT NULL DEFAULT '',
`version` varchar(255) NOT NULL DEFAULT '',
`snap` mediumtext NOT NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_api`;
CREATE TABLE `zt_api`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`product` varchar(255) NOT NULL DEFAULT '',
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`module` int UNSIGNED NOT NULL DEFAULT 0,
`title` varchar(100) NOT NULL DEFAULT '',
`path` varchar(255) NOT NULL DEFAULT '',
`protocol` varchar(10) NOT NULL DEFAULT '',
`method` varchar(10) NOT NULL DEFAULT '',
`requestType` varchar(100) NOT NULL DEFAULT '',
`responseType` varchar(100) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
`owner` varchar(30) NOT NULl DEFAULT 0,
`desc` text NULL,
`version` smallint UNSIGNED NOT NULL DEFAULT 0,
`params` text NULL,
`paramsExample` text NUll,
`responseExample` text NUll,
`response` text NULL,
`commonParams` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL DEFAULT 0,
`editedDate` datetime NOT NULL,
`deleted` enum ('0', '1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
CREATE TABLE `zt_api` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`product` varchar(255) NOT NULL DEFAULT '',
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`module` int UNSIGNED NOT NULL DEFAULT 0,
`title` varchar(100) NOT NULL DEFAULT '',
`path` varchar(255) NOT NULL DEFAULT '',
`protocol` varchar(10) NOT NULL DEFAULT '',
`method` varchar(10) NOT NULL DEFAULT '',
`requestType` varchar(100) NOT NULL DEFAULT '',
`responseType` varchar(100) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
`owner` varchar(30) NOT NULl DEFAULT 0,
`desc` text NULL,
`version` smallint UNSIGNED NOT NULL DEFAULT 0,
`params` text NULL,
`paramsExample` text NUll,
`responseExample` text NUll,
`response` text NULL,
`commonParams` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL DEFAULT 0,
`editedDate` datetime NOT NULL,
`deleted` enum ('0', '1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_apispec`;
CREATE TABLE `zt_apispec`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`doc` int UNSIGNED NOT NULL DEFAULT 0,
`module` int UNSIGNED NOT NULL DEFAULT 0,
`title` varchar(100) NOT NULL DEFAULT '',
`path` varchar(255) NOT NULL DEFAULT '',
`protocol` varchar(10) NOT NULL DEFAULT '',
`method` varchar(10) NOT NULL DEFAULT '',
`requestType` varchar(100) NOT NULL DEFAULT '',
`responseType` varchar(100) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
`owner` varchar(255) NOT NULl DEFAULT 0,
`desc` text NULL,
`version` smallint UNSIGNED NOT NULL DEFAULT 0,
`params` text NULL,
`paramsExample` text NUll,
`responseExample` text NUll,
`response` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NULL,
PRIMARY KEY (`id`)
CREATE TABLE `zt_apispec` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`doc` int UNSIGNED NOT NULL DEFAULT 0,
`module` int UNSIGNED NOT NULL DEFAULT 0,
`title` varchar(100) NOT NULL DEFAULT '',
`path` varchar(255) NOT NULL DEFAULT '',
`protocol` varchar(10) NOT NULL DEFAULT '',
`method` varchar(10) NOT NULL DEFAULT '',
`requestType` varchar(100) NOT NULL DEFAULT '',
`responseType` varchar(100) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
`owner` varchar(255) NOT NULl DEFAULT 0,
`desc` text NULL,
`version` smallint UNSIGNED NOT NULL DEFAULT 0,
`params` text NULL,
`paramsExample` text NUll,
`responseExample` text NUll,
`response` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_apistruct`;
CREATE TABLE `zt_apistruct`
(
`id` int unsigned NOT NULL AUTO_INCREMENT,
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`name` varchar(30) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` text NOT NULL DEFAULT '',
`version` smallint unsigned NOT NULL DEFAULT 0,
`attribute` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
`editEdBy` varchar(30) NOT NULL DEFAULT 0,
`editedDate` datetime NOT NULL,
`deleted` enum ('0', '1') NOT NULL DEFAULT '0',
primary key (`id`)
CREATE TABLE `zt_apistruct` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`name` varchar(30) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` varchar(255) NOT NULL DEFAULT '',
`version` smallint unsigned NOT NULL DEFAULT 0,
`attribute` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
`editEdBy` varchar(30) NOT NULL DEFAULT 0,
`editedDate` datetime NOT NULL,
`deleted` enum ('0', '1') NOT NULL DEFAULT '0',
primary key (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_apistruct_spec`;
CREATE TABLE `zt_apistruct_spec`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` varchar(255) NOT NULL DEFAULT '',
`attribute` text NULL,
`version` smallint unsigned NOT NULL DEFAULT 0,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
primary key (`id`)
CREATE TABLE `zt_apistruct_spec` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` varchar(255) NOT NULL DEFAULT '',
`attribute` text NULL,
`version` smallint unsigned NOT NULL DEFAULT 0,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
`addedDate` datetime NOT NULL,
primary key (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_block`;
CREATE TABLE IF NOT EXISTS `zt_block` (
@@ -187,6 +182,8 @@ CREATE TABLE IF NOT EXISTS `zt_bug` (
`confirmed` tinyint(1) NOT NULL default '0',
`activatedCount` smallint(6) NOT NULL,
`activatedDate` datetime NOT NULL,
`feedbackBy` varchar(100) NOT NULL,
`notifyEmail` varchar(100) NOT NULL,
`mailto` text,
`openedBy` varchar(30) NOT NULL default '',
`openedDate` datetime NOT NULL,
@@ -398,6 +395,39 @@ CREATE TABLE IF NOT EXISTS `zt_dept` (
KEY `parent` (`parent`),
KEY `path` (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_design`;
CREATE TABLE IF NOT EXISTS `zt_design` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`project` varchar(255) NOT NULL,
`product` varchar(255) NOT NULL,
`commit` text NOT NULL,
`commitedBy` varchar(30) NOT NULL,
`execution` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`status` varchar(30) NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`assignedBy` varchar(30) NOT NULL,
`assignedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`story` char(30) NOT NULL,
`desc` text NOT NULL,
`version` smallint(6) NOT NULL,
`type` char(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_designspec`;
CREATE TABLE IF NOT EXISTS `zt_designspec` (
`design` mediumint(8) NOT NULL,
`version` smallint(6) NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`files` varchar(255) NOT NULL,
UNIQUE KEY `design` (`design`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_doc`;
CREATE TABLE IF NOT EXISTS `zt_doc` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
@@ -563,6 +593,19 @@ CREATE TABLE IF NOT EXISTS `zt_grouppriv` (
`method` char(30) NOT NULL default '',
UNIQUE KEY `group` (`group`,`module`,`method`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_holiday`;
CREATE TABLE IF NOT EXISTS `zt_holiday` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '',
`type` enum('holiday', 'working') NOT NULL DEFAULT 'holiday',
`desc` text NOT NULL,
`year` char(4) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
PRIMARY KEY (`id`),
KEY `year` (`year`),
KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_history`;
CREATE TABLE IF NOT EXISTS `zt_history` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
@@ -600,6 +643,34 @@ CREATE TABLE IF NOT EXISTS `zt_job` (
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_kanbanlane`;
CREATE TABLE IF NOT EXISTS `zt_kanbanlane` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`execution` mediumint(8) NOT NULL DEFAULT '0',
`type` char(30) NOT NULL,
`groupby` char(30) NOT NULL,
`extra` char(30) NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`color` char(30) NOT NULL,
`order` smallint(6) NOT NULL DEFAULT '0',
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_kanbancolumn`;
CREATE TABLE IF NOT EXISTS `zt_kanbancolumn` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`lane` mediumint(8) NOT NULL DEFAULT '0',
`parent` mediumint(8) NOT NULL DEFAULT '0',
`type` char(30) NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`color` char(30) NOT NULL,
`limit` smallint(6) NOT NULL DEFAULT '-1',
`order` mediumint(8) NOT NULL DEFAULT '0',
`cards` text NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_lang`;
CREATE TABLE IF NOT EXISTS `zt_lang` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
@@ -738,6 +809,7 @@ CREATE TABLE IF NOT EXISTS `zt_product` (
`RD` varchar(30) NOT NULL,
`acl` enum('open','private','custom') NOT NULL default 'open',
`whitelist` text NOT NULL,
`reviewer` varchar(255) NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`createdVersion` varchar(20) NOT NULL,
@@ -995,6 +1067,19 @@ CREATE TABLE IF NOT EXISTS `zt_searchindex` (
FULLTEXT KEY `content` (`content`),
FULLTEXT KEY `title` (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_stage`;
CREATE TABLE IF NOT EXISTS `zt_stage` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`percent` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_stakeholder`;
CREATE TABLE IF NOT EXISTS `zt_stakeholder` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -1049,6 +1134,8 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
`linkStories` varchar(255) NOT NULL,
`duplicateStory` mediumint(8) unsigned NOT NULL,
`version` smallint(6) NOT NULL default '1',
`feedbackBy` varchar(100) NOT NULL,
`notifyEmail` varchar(100) NOT NULL,
`URChanged` enum('0','1') NOT NULL DEFAULT '0',
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
@@ -1415,6 +1502,22 @@ CREATE TABLE IF NOT EXISTS `zt_userview` (
`sprints` mediumtext NOT NULL,
UNIQUE KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_weeklyreport`;
CREATE TABLE IF NOT EXISTS `zt_weeklyreport`(
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`project` mediumint(8) unsigned NOT NULL,
`weekStart` date NOT NULL,
`pv` float(9,2) NOT NULL,
`ev` float(9,2) NOT NULL,
`ac` float(9,2) NOT NULL,
`sv` float(9,2) NOT NULL,
`cv` float(9,2) NOT NULL,
`staff` smallint(5) unsigned NOT NULL,
`progress` varchar(255) NOT NULL,
`workload` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `week` (`project`,`weekStart`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_webhook`;
CREATE TABLE IF NOT EXISTS `zt_webhook` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
@@ -5701,7 +5804,22 @@ 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');
('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');
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');
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');
+1 -4
View File
@@ -945,10 +945,7 @@ class baseControl
*/
public function sendError($error)
{
$this->send(array(
'result' => 'fail',
'message' => $error,
));
$this->send(array('result' => 'fail', 'message' => $error));
}
/**
+1 -2
View File
@@ -229,7 +229,7 @@ class html extends baseHTML
/**
* Create user avatar.
*
* @param string|object|array $user User object or user avatar url or user account
* @param string|object|array $user User object or user account
* @param string|int $size Avatar size, can be a number or preset sizes: "xs", "sm", "", "lg", "xl", default is ""
* @param string $className Avatar element class name, default is "avatar-circle"
* @param string $attrib Extra attributes on avatar element
@@ -248,7 +248,6 @@ class html extends baseHTML
if(is_string($user))
{
$userObj->account = $user;
if(strlen($user) > 1) $userObj->avatar = $user;
$user = $userObj;
}
elseif(is_array($user))
-29
View File
@@ -1,29 +0,0 @@
Software License Agreement (BSD License)
Copyright (c) 2015, SegmentFault
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of schillmania.com nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission from schillmania.com.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013-2018 Emanuil Rusev, erusev.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File diff suppressed because it is too large Load Diff
-4
View File
@@ -90,14 +90,10 @@ class gitlab
/**
* Get files info.
*
* The API path requested is: "GET /projects/:id/repository/files/:file_path".
* Known issue of GitLab API: if a '%' in 'file_path', GitLab API will show a error 'file_path should be a valid file path'.
*
* @param string $path
* @param string $ref
* @access public
* @return array
* @doc https://docs.gitlab.com/ee/api/repository_files.html
*/
public function files($path, $ref = 'master')
{
+36 -34
View File
@@ -1,37 +1,39 @@
<?php
$config->action->objectNameFields['product'] = 'name';
$config->action->objectNameFields['story'] = 'title';
$config->action->objectNameFields['productplan'] = 'title';
$config->action->objectNameFields['release'] = 'name';
$config->action->objectNameFields['program'] = 'name';
$config->action->objectNameFields['project'] = 'name';
$config->action->objectNameFields['execution'] = 'name';
$config->action->objectNameFields['task'] = 'name';
$config->action->objectNameFields['build'] = 'name';
$config->action->objectNameFields['bug'] = 'title';
$config->action->objectNameFields['testcase'] = 'title';
$config->action->objectNameFields['case'] = 'title';
$config->action->objectNameFields['testtask'] = 'name';
$config->action->objectNameFields['user'] = 'account';
$config->action->objectNameFields['api'] = 'title';
$config->action->objectNameFields['doc'] = 'title';
$config->action->objectNameFields['doclib'] = 'name';
$config->action->objectNameFields['todo'] = 'name';
$config->action->objectNameFields['branch'] = 'name';
$config->action->objectNameFields['module'] = 'name';
$config->action->objectNameFields['testsuite'] = 'name';
$config->action->objectNameFields['caselib'] = 'name';
$config->action->objectNameFields['testreport'] = 'title';
$config->action->objectNameFields['entry'] = 'name';
$config->action->objectNameFields['webhook'] = 'name';
$config->action->objectNameFields['risk'] = 'name';
$config->action->objectNameFields['issue'] = 'title';
$config->action->objectNameFields['design'] = 'name';
$config->action->objectNameFields['stakeholder'] = 'user';
$config->action->objectNameFields['budget'] = 'name';
$config->action->objectNameFields['job'] = 'name';
$config->action->objectNameFields['team'] = 'name';
$config->action->objectNameFields['pipeline'] = 'name';
$config->action->objectNameFields['product'] = 'name';
$config->action->objectNameFields['story'] = 'title';
$config->action->objectNameFields['productplan'] = 'title';
$config->action->objectNameFields['release'] = 'name';
$config->action->objectNameFields['program'] = 'name';
$config->action->objectNameFields['project'] = 'name';
$config->action->objectNameFields['execution'] = 'name';
$config->action->objectNameFields['task'] = 'name';
$config->action->objectNameFields['build'] = 'name';
$config->action->objectNameFields['bug'] = 'title';
$config->action->objectNameFields['testcase'] = 'title';
$config->action->objectNameFields['case'] = 'title';
$config->action->objectNameFields['testtask'] = 'name';
$config->action->objectNameFields['user'] = 'account';
$config->action->objectNameFields['api'] = 'title';
$config->action->objectNameFields['doc'] = 'title';
$config->action->objectNameFields['doclib'] = 'name';
$config->action->objectNameFields['todo'] = 'name';
$config->action->objectNameFields['branch'] = 'name';
$config->action->objectNameFields['module'] = 'name';
$config->action->objectNameFields['testsuite'] = 'name';
$config->action->objectNameFields['caselib'] = 'name';
$config->action->objectNameFields['testreport'] = 'title';
$config->action->objectNameFields['entry'] = 'name';
$config->action->objectNameFields['webhook'] = 'name';
$config->action->objectNameFields['risk'] = 'name';
$config->action->objectNameFields['issue'] = 'title';
$config->action->objectNameFields['design'] = 'name';
$config->action->objectNameFields['stakeholder'] = 'user';
$config->action->objectNameFields['budget'] = 'name';
$config->action->objectNameFields['job'] = 'name';
$config->action->objectNameFields['team'] = 'name';
$config->action->objectNameFields['pipeline'] = 'name';
$config->action->objectNameFields['kanbancolumn'] = 'name';
$config->action->objectNameFields['kanbanlane'] = 'name';
$config->action->commonImgSize = 870;
@@ -46,5 +48,5 @@ $config->action->majorList['project'] = array('opened', 'edited');
$config->action->majorList['execution'] = array('opened', 'edited');
$config->action->needGetProjectType = 'build,task,bug,case,testcase,caselib,testtask,testsuite,testreport,doc,issue,release,risk,design,opportunity,trainplan,gapanalysis,researchplan,researchreport,';
$config->action->needGetRelateField = ',story,productplan,release,task,build,bug,case,testtask,testreport,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,branch,';
$config->action->needGetRelateField = ',story,productplan,release,task,build,bug,case,testtask,testreport,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,kanbanlane,kanbancolumn,';
$config->action->noLinkModules = ',doclib,module,webhook,gitlab,pipeline,jenkins,';
+26 -21
View File
@@ -369,6 +369,10 @@ $lang->action->dynamicAction->execution['undeleted'] = 'Restore ' . $lang->execu
$lang->action->dynamicAction->execution['hidden'] = 'Hide ' . $lang->executionCommon;
$lang->action->dynamicAction->execution['moved'] = 'Improt Task';
$lang->action->dynamicAction->kanbancolumn['edited'] = 'Column Settings';
$lang->action->dynamicAction->kanbanlane['edited'] = 'Swimlane Settings';
$lang->action->dynamicAction->kanbanlane['moved'] = 'Move Swimlane';
$lang->action->dynamicAction->team['managedTeam'] = 'Manage Team';
$lang->action->dynamicAction->task['opened'] = 'Create Task';
@@ -500,27 +504,28 @@ else
{
$lang->action->label->execution = "$lang->executionCommon|execution|task|executionID=%s";
}
$lang->action->label->task = 'Task|task|view|taskID=%s';
$lang->action->label->build = 'Build|build|view|buildID=%s';
$lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = 'Case|testcase|view|caseID=%s';
$lang->action->label->testtask = 'Request|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Test Suite|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Case Library|caselib|view|libID=%s';
$lang->action->label->todo = 'Todo|todo|view|todoID=%s';
$lang->action->label->doclib = 'Doc Library|doc|objectLibs|type=%s&objectID=%s&libID=%s&docID=&version=&appendLib=%s';
$lang->action->label->doc = 'Doc|doc|view|docID=%s';
$lang->action->label->user = 'User|user|view|account=%s';
$lang->action->label->testreport = 'Report|testreport|view|report=%s';
$lang->action->label->entry = 'Application|entry|browse|';
$lang->action->label->webhook = 'Webhook|webhook|browse|';
$lang->action->label->space = ' ';
$lang->action->label->risk = 'Risk|risk|view|riskID=%s';
$lang->action->label->issue = 'Issue|issue|view|issueID=%s';
$lang->action->label->design = 'Design|design|view|designID=%s';
$lang->action->label->stakeholder = 'Stakeholder|stakeholder|view|userID=%s';
$lang->action->label->api = 'Interface|api|index|libID=%s&moduleID=%s&apiID=%s';
$lang->action->label->branch = 'Branch|branch|manage|prouctID=%s&browseType=all';
$lang->action->label->task = 'Task|task|view|taskID=%s';
$lang->action->label->build = 'Build|build|view|buildID=%s';
$lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = 'Case|testcase|view|caseID=%s';
$lang->action->label->testtask = 'Request|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Test Suite|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Case Library|caselib|view|libID=%s';
$lang->action->label->todo = 'Todo|todo|view|todoID=%s';
$lang->action->label->doclib = 'Doc Library|doc|objectLibs|type=%s&objectID=%s&libID=%s';
$lang->action->label->doc = 'Doc|doc|view|docID=%s';
$lang->action->label->user = 'User|user|view|account=%s';
$lang->action->label->testreport = 'Report|testreport|view|report=%s';
$lang->action->label->entry = 'Application|entry|browse|';
$lang->action->label->webhook = 'Webhook|webhook|browse|';
$lang->action->label->space = ' ';
$lang->action->label->risk = 'Risk|risk|view|riskID=%s';
$lang->action->label->issue = 'Issue|issue|view|issueID=%s';
$lang->action->label->design = 'Design|design|view|designID=%s';
$lang->action->label->stakeholder = 'Stakeholder|stakeholder|view|userID=%s';
$lang->action->label->api = 'Interface|api|index|libID=%s&moduleID=%s&apiID=%s';
$lang->action->label->kanbancolumn = 'Kanban column|execution|kanban|execution=%s';
$lang->action->label->kanbanlane = 'Kanban Lane|execution|kanban|execution=%s&type=all';
/* Object type. */
$lang->action->search = new stdclass();
+26 -21
View File
@@ -372,6 +372,10 @@ $lang->action->dynamicAction->execution['undeleted'] = '还原' . $lang->executi
$lang->action->dynamicAction->execution['hidden'] = '隐藏' . $lang->executionCommon;
$lang->action->dynamicAction->execution['moved'] = '导入任务';
$lang->action->dynamicAction->kanbancolumn['edited'] = '设置看板列';
$lang->action->dynamicAction->kanbanlane['edited'] = '设置泳道';
$lang->action->dynamicAction->kanbanlane['moved'] = '移动泳道';
$lang->action->dynamicAction->team['managedTeam'] = '维护团队';
$lang->action->dynamicAction->task['opened'] = '创建任务';
@@ -503,27 +507,28 @@ else
{
$lang->action->label->execution = "$lang->executionCommon|execution|task|executionID=%s";
}
$lang->action->label->task = '任务|task|view|taskID=%s';
$lang->action->label->build = '版本|build|view|buildID=%s';
$lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = '用例|testcase|view|caseID=%s';
$lang->action->label->testtask = '测试单|testtask|view|caseID=%s';
$lang->action->label->testsuite = '测试套件|testsuite|view|suiteID=%s';
$lang->action->label->caselib = '用例库|caselib|view|libID=%s';
$lang->action->label->todo = '待办|todo|view|todoID=%s';
$lang->action->label->doclib = '文档库|doc|tablecontents|type=%s&objectID=%s&libID=%s';
$lang->action->label->doc = '文档|doc|view|docID=%s';
$lang->action->label->user = '用户|user|view|account=%s';
$lang->action->label->testreport = '报告|testreport|view|report=%s';
$lang->action->label->entry = '应用|entry|browse|';
$lang->action->label->webhook = 'Webhook|webhook|browse|';
$lang->action->label->space = ' ';
$lang->action->label->risk = '风险|risk|view|riskID=%s';
$lang->action->label->issue = '问题|issue|view|issueID=%s';
$lang->action->label->design = '设计|design|view|designID=%s';
$lang->action->label->stakeholder = '干系人|stakeholder|view|userID=%s';
$lang->action->label->api = '接口|api|index|libID=%s&moduleID=%s&apiID=%s';
$lang->action->label->branch = '分支|branch|manage|productID=%s&browseType=all';
$lang->action->label->task = '任务|task|view|taskID=%s';
$lang->action->label->build = '版本|build|view|buildID=%s';
$lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = '用例|testcase|view|caseID=%s';
$lang->action->label->testtask = '测试单|testtask|view|caseID=%s';
$lang->action->label->testsuite = '测试套件|testsuite|view|suiteID=%s';
$lang->action->label->caselib = '用例库|caselib|view|libID=%s';
$lang->action->label->todo = '待办|todo|view|todoID=%s';
$lang->action->label->doclib = '文档库|doc|tablecontents|type=%s&objectID=%s&libID=%s';
$lang->action->label->doc = '文档|doc|view|docID=%s';
$lang->action->label->user = '用户|user|view|account=%s';
$lang->action->label->testreport = '报告|testreport|view|report=%s';
$lang->action->label->entry = '应用|entry|browse|';
$lang->action->label->webhook = 'Webhook|webhook|browse|';
$lang->action->label->space = ' ';
$lang->action->label->risk = '风险|risk|view|riskID=%s';
$lang->action->label->issue = '问题|issue|view|issueID=%s';
$lang->action->label->design = '设计|design|view|designID=%s';
$lang->action->label->stakeholder = '干系人|stakeholder|view|userID=%s';
$lang->action->label->api = '接口|api|index|libID=%s&moduleID=%s&apiID=%s';
$lang->action->label->kanbancolumn = '看板列|execution|kanban|execution=%s';
$lang->action->label->kanbanlane = '看板泳道|execution|kanban|execution=%s&type=all';
/* Object type. */
$lang->action->search = new stdclass();
+26 -6
View File
@@ -66,8 +66,6 @@ class actionModel extends model
$action->product = $relation['product'];
$action->project = (int)$relation['project'];
$action->execution = (int)$relation['execution'];
$this->dao->insert(TABLE_ACTION)->data($action)->autoCheck()->exec();
$actionID = $this->dao->lastInsertID();
@@ -190,7 +188,7 @@ class actionModel extends model
$fields = '*';
if(strpos('story, productplan, case, branch', $objectType) !== false) $fields = 'product';
if(strpos('build, bug, testtask, doc', $objectType) !== false) $fields = 'product, project, execution';
if(strpos('case, repo', $objectType) !== false) $fields = 'execution';
if(strpos('case, repo, kanbanlane', $objectType) !== false) $fields = 'execution';
if($objectType == 'release') $fields = 'product, build';
if($objectType == 'task') $fields = 'project, execution, story';
@@ -199,6 +197,8 @@ class actionModel extends model
/* Process story, release and task. */
if($objectType == 'story') $record->project = $this->dao->select('project')->from(TABLE_PROJECTSTORY)->where('story')->eq($objectID)->orderBy('project_desc')->limit(1)->fetch('project');
if($objectType == 'release') $record->project = $this->dao->select('project')->from(TABLE_BUILD)->where('id')->eq($record->build)->fetch('project');
if($objectType == 'kanbanlane') $record->execution = $this->dao->select($fields)->from(TABLE_KANBANLANE)->where('id')->eq($objectID)->fetch('execution');
if($objectType == 'kanbancolumn') $record->execution = $extra;
if($objectType == 'team')
{
$team = $this->dao->select('type')->from(TABLE_PROJECT)->where('id')->eq($objectID)->fetch();
@@ -818,7 +818,7 @@ class actionModel extends model
if(!$actions) return array();
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'action');
return $this->transformActions($actions);;
return $this->transformActions($actions);
}
/**
@@ -1199,6 +1199,10 @@ class actionModel extends model
{
$params = sprintf($vars, trim($action->product, ','));
}
elseif($action->objectType == 'kanbancolumn' or $action->objectType == 'kanbanlane')
{
$params = sprintf($vars, $action->extra);
}
else
{
$params = sprintf($vars, $action->objectID);
@@ -1233,6 +1237,11 @@ class actionModel extends model
if($action->objectType == 'stakeholder' and $action->project == 0) $action->objectLink = '';
if($action->objectType == 'story' and $action->action == 'import2storylib')
{
$action->objectLink = helper::createLink('assetlib', 'storyView', "storyID=$action->objectID");
}
return $action;
}
@@ -1436,10 +1445,11 @@ class actionModel extends model
* @param array $actions
* @param string $direction
* @param string $type all|today|yesterday|thisweek|lastweek|thismonth|lastmonth
* @param string $orderBy date_desc|date_asc
* @access public
* @return array
*/
public function buildDateGroup($actions, $direction = 'next', $type = 'today')
public function buildDateGroup($actions, $direction = 'next', $type = 'today', $orderBy = 'date_desc')
{
$dateGroup = array();
foreach($actions as $action)
@@ -1467,7 +1477,17 @@ class actionModel extends model
}
}
if($direction != 'next') $dateGroup = array_reverse($dateGroup);
/* Modify date to the corrret order. */
if($this->app->rawModule != 'company' and $direction != 'next')
{
$dateGroup = array_reverse($dateGroup);
}
elseif($this->app->rawModule == 'company' and (($direction == 'next' and $orderBy == 'date_asc') or ($direction == 'pre' and $orderBy == 'date_desc')))
{
$dateGroup = array_reverse($dateGroup);
foreach($dateGroup as $key => $dateItem) $dateGroup[$key] = array_reverse($dateItem);
}
return $dateGroup;
}
+7 -17
View File
@@ -67,7 +67,7 @@ class api extends control
$this->view->apiList = $apiList;
}
$this->setMenu($libID, $moduleID);
$this->setMenu($libID);
$this->view->isRelease = $release > 0;
$this->view->release = $release;
@@ -435,21 +435,17 @@ class api extends control
$this->setMenu($api->lib);
$example = array('example' => 'type,description');
$example = json_encode($example, JSON_PRETTY_PRINT);
$options = array();
foreach($this->lang->api->paramsTypeOptions as $key => $item)
{
$options[] = array('label' => $item, 'value' => $key);
}
$this->view->typeOptions = $options;
$this->view->gobackLink = $this->createLink('api', 'index', "libID={$api->lib}&moduleID={$api->module}");
$this->view->user = $this->app->user->account;
$this->view->allUsers = $this->loadModel('user')->getPairs('devfirst|noclosed');;
$this->view->typeOptions = $options;
$this->view->gobackLink = $this->createLink('api', 'index', "libID={$api->lib}&moduleID={$api->module}");
$this->view->user = $this->app->user->account;
$this->view->allUsers = $this->loadModel('user')->getPairs('devfirst|noclosed');;
$this->view->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($api->lib, 'api', $startModuleID = 0);
$this->view->moduleID = $api->module ? (int)$api->module : (int)$this->cookie->lastDocModule;
$this->view->example = $example;
$this->view->title = $api->title . $this->lang->api->edit;
$this->display();
@@ -469,7 +465,6 @@ class api extends control
{
$now = helper::now();
$params = fixer::input('post')
->trim('title,path')
->remove('type')
->skipSpecial('params,response')
->add('addedBy', $this->app->user->account)
@@ -495,9 +490,6 @@ class api extends control
$lib = $this->doc->getLibByID($libID);
$libName = isset($lib->name) ? $lib->name . $this->lang->colon : '';
$example = array('example' => 'type,description');
$example = json_encode($example, JSON_PRETTY_PRINT);
$this->getTypeOptions($libID);
$this->view->gobackLink = $this->createLink('api', 'index', "libID=$libID&moduleID=$moduleID");
$this->view->user = $this->app->user->account;
@@ -507,7 +499,6 @@ class api extends control
$this->view->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'api', $startModuleID = 0);
$this->view->moduleID = $moduleID ? (int)$moduleID : (int)$this->cookie->lastDocModule;
$this->view->libs = $libs;
$this->view->example = $example;
$this->view->title = $libName . $this->lang->api->create;
$this->view->users = $this->user->getPairs('nocode');
@@ -613,11 +604,10 @@ class api extends control
* Set doc menu by method name.
*
* @param int $libID
* @param int $moduleID
* @access public
* @return void
*/
private function setMenu($libID = 0, $moduleID = 0)
private function setMenu($libID = 0)
{
common::setMenuVars('doc', $libID);
@@ -642,7 +632,7 @@ class api extends control
if(common::hasPriv('api', 'create'))
{
$menu .= "<li>";
$menu .= html::a(helper::createLink('api', 'create', "libID=$libID&moduleID=$moduleID"), "<i class='icon-rich-text icon'></i> " . $this->lang->api->apiDoc, '', "data-app='{$this->app->tab}'");
$menu .= html::a(helper::createLink('api', 'create', "libID=$libID"), "<i class='icon-rich-text icon'></i> " . $this->lang->api->apiDoc, '', "data-app='{$this->app->tab}'");
$menu .= "</li>";
}
+48 -48
View File
@@ -14,53 +14,53 @@ $lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->index = 'Api Doc Home';
$lang->api->editLib = 'Edit Api Doc';
$lang->api->releases = 'Releases';
$lang->api->index = 'Home';
$lang->api->editLib = 'Edit';
$lang->api->releases = 'Release';
$lang->api->deleteRelease = 'Delete Release';
$lang->api->deleteLib = 'Delete Api Doc';
$lang->api->deleteLib = 'Delete API Doc';
$lang->api->createRelease = 'Publish';
$lang->api->createLib = 'Create Api Library';
$lang->api->createApi = 'Create Api';
$lang->api->createLib = 'Create API Library';
$lang->api->createApi = 'Create API Document';
$lang->api->createAB = 'Create';
$lang->api->edit = 'Edit';
$lang->api->delete = 'Delete';
$lang->api->position = 'Positions';
$lang->api->position = 'Position';
$lang->api->startLine = "%s,%s";
$lang->api->desc = 'Description';
$lang->api->debug = 'Debug';
$lang->api->submit = 'Submit';
$lang->api->url = 'Url';
$lang->api->url = 'URL';
$lang->api->result = 'Result';
$lang->api->status = 'Status';
$lang->api->data = 'Content';
$lang->api->noParam = 'Get debugging does not require input parameters,';
$lang->api->noModule = 'There is no directory under the interface library. Please maintain the directory first';
$lang->api->noModule = 'No directory in the API library. Please add the directory first';
$lang->api->post = 'Please refer to the page form for post debugging';
$lang->api->noUniqueName = 'Api library name already exists。';
$lang->api->noUniqueVersion = 'Version already exists。';
$lang->api->noUniqueName = 'The API library name exists.';
$lang->api->noUniqueVersion = 'The version exists.';
$lang->api->version = 'Version';
$lang->api->createStruct = 'Create Data Structure';
$lang->api->editStruct = 'Edit Data Structure';
$lang->api->deleteStruct = 'Delete Data Structure';
$lang->api->create = 'Ceate Doc';
$lang->api->title = 'Interface Name';
$lang->api->pageTitle = 'Api Library';
$lang->api->create = 'Create API';
$lang->api->title = 'Name';
$lang->api->pageTitle = 'API Library';
$lang->api->module = 'Directory';
$lang->api->apiDoc = 'Interface';
$lang->api->apiDoc = 'API';
$lang->api->manageType = 'Manage Directory';
$lang->api->managePublish = 'Manage Version';
$lang->api->doing = 'Doing';
$lang->api->done = 'Done';
$lang->api->basicInfo = 'Essential Information';
$lang->api->apiDesc = 'Interface Description';
$lang->api->confirmDelete = "Are you sure to delete this interface?";
$lang->api->confirmDeleteLib = "Are you sure to delete this interface library?";
$lang->api->basicInfo = 'Basic Information';
$lang->api->apiDesc = 'Description';
$lang->api->confirmDelete = "Do you want to delete this API?";
$lang->api->confirmDeleteLib = "Do you want to delete this interface library?";
$lang->api->filterStruct = "use struct";
$lang->api->defaultVersion = "Current Version";
/* Common access control lang. */
$lang->api->whiteList = 'White list';
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
@@ -68,9 +68,9 @@ $lang->api->group = 'Group';
$lang->api->user = 'User';
$lang->api->noticeAcl = array(
'open' => 'Users who can access the api library which the library belongs can access it.',
'custom' => 'Users in the whiltelist can access it.',
'private' => 'Only the one who created it can access it.',
'open' => 'Users who can access the API library can access it.',
'custom' => 'Users on the whiltelist can access it.',
'private' => 'Only the one who creates it can access it.',
);
/* fields of struct */
@@ -81,7 +81,7 @@ $lang->struct->field = 'Field';
$lang->struct->paramsType = 'Type';
$lang->struct->required = 'Require';
$lang->struct->desc = 'Description';
$lang->struct->descPlaceholder = 'Parameter description';
$lang->struct->descPlaceholder = 'Parameter Description';
$lang->struct->action = 'Action';
$lang->struct->addSubField = 'Add Subfield';
@@ -94,36 +94,36 @@ $lang->struct->typeOptions = array(
/* fields of form */
$lang->api->struct = 'Data Structure';
$lang->api->structName = 'Structure Name';
$lang->api->structName = 'Name';
$lang->api->structType = 'Type';
$lang->api->structAttr = 'Attribute';
$lang->api->structAddedBy = 'Creator';
$lang->api->structAddedDate = 'Created Time';
$lang->api->name = 'Interface Library Name';
$lang->api->baseUrl = 'Base Url';
$lang->api->baseUrlDesc = 'Site or path. for example, api.zentao.com or /v1';
$lang->api->structAddedBy = 'CreatedBy';
$lang->api->structAddedDate = 'Created';
$lang->api->name = 'API Library Name';
$lang->api->baseUrl = 'Base URL';
$lang->api->baseUrlDesc = 'Site or path, e.g., api.zentao.com or /v1.';
$lang->api->desc = 'Description';
$lang->api->control = 'Access Control';
$lang->api->noLib = 'There is no interface library at present。';
$lang->api->noApi = 'There is no interface for the time being。';
$lang->api->noStruct = 'There is no structure for the time being。';
$lang->api->lib = 'Interface Library';
$lang->api->apiList = 'Interface List';
$lang->api->formTitle = 'Interface Name';
$lang->api->noLib = 'No API library yet.';
$lang->api->noApi = 'No API yet.';
$lang->api->noStruct = 'No API yet.';
$lang->api->lib = 'API Library';
$lang->api->apiList = 'API List';
$lang->api->formTitle = 'API Name';
$lang->api->path = 'Request Path';
$lang->api->protocol = 'Request Protocol';
$lang->api->method = 'Request Method';
$lang->api->requestType = 'Request Type';
$lang->api->status = 'Development Status';
$lang->api->owner = 'Person In Charge';
$lang->api->paramsExample = 'Response Example';
$lang->api->protocol = 'Protocol';
$lang->api->method = 'Method';
$lang->api->requestType = 'Type';
$lang->api->status = 'Status';
$lang->api->owner = 'Owner';
$lang->api->paramsExample = 'Request Example';
$lang->api->header = 'Request Header';
$lang->api->query = 'Request Parameters';
$lang->api->query = 'Parameter';
$lang->api->params = 'Request Body';
$lang->api->response = 'Response';
$lang->api->responseExample = 'Response Example';
$lang->api->res = new stdClass();
$lang->api->res->name = '名称';
$lang->api->res->name = 'Name';
$lang->api->res->desc = 'Description';
$lang->api->res->type = 'Type';
$lang->api->req = new stdClass();
@@ -198,14 +198,14 @@ $lang->api->allParamsTypeOptions = array_merge($lang->api->paramsTypeOptions, $l
$lang->api->requiredOptions = array(0 => 'No', 1 => 'Yes');
$lang->doclib = new stdclass();
$lang->doclib->name = 'Interface Library Name';
$lang->doclib->name = 'API Library Name';
$lang->apistruct = new stdClass();
$lang->apistruct->name = 'Structure Name';
$lang->apistruct->name = 'Name';
$lang->api_lib_release = new stdClass();
$lang->api_lib_release->version = 'Version';
$lang->api->error = new stdclass();
$lang->api->error->onlySelect = 'SQL interface only allow SELECT query.';
$lang->api->error->disabled = 'For security reasons, this feature is disabled. You can go to the config directory and modify the configuration item %s to open this function.';
$lang->api->error->onlySelect = 'SQL API only allows SELECT query.';
$lang->api->error->disabled = 'For security reasons, this feature is disabled. Go to the config directory and modify the configuration item %s to enable it.';
+1 -1
View File
@@ -41,7 +41,7 @@ $lang->api->noUniqueName = '接口库名已存在。';
$lang->api->noUniqueVersion = '版本已存在。';
$lang->api->version = '版本';
$lang->api->createStruct = '创建数据结构';
$lang->api->editStruct = '编辑数据结构';
$lang->api->editStruct = '修改数据结构';
$lang->api->deleteStruct = '删除数据结构';
$lang->api->create = '创建接口';
$lang->api->title = '接口名称';
+9 -10
View File
@@ -209,29 +209,28 @@ class apiModel extends model
$now = helper::now();
$account = $this->app->user->account;
$data = fixer::input('post')
->remove('type')
->skipSpecial('params,response')
->add('editedBy', $account)
->add('editedDate', $now)
->add('version', $oldApi->version)
->setDefault('product,module', 0)
->remove('type')
->get();
$changes = common::createChanges($oldApi, $data);
if(!empty($changes)) $data->version = $oldApi->version + 1;
$data->id = $oldApi->id;
$data->version = $oldApi->version + 1;
$apiSpec = $this->getApiSpecByData($data);
$this->dao->replace(TABLE_API_SPEC)->data($apiSpec)->exec();
unset($data->id);
$this->dao->update(TABLE_API)
->data($data)
->autoCheck()
->batchCheck($this->config->api->edit->requiredFields, 'notempty')
->where('id')->eq($apiID)
->exec();
$data->id = $apiID;
$apiSpec = $this->getApiSpecByData($data);
$this->dao->replace(TABLE_API_SPEC)->data($apiSpec)->exec();
return $changes;
return common::createChanges($oldApi, $data);
}
/**
+2 -9
View File
@@ -1,4 +1,4 @@
<div class="main-col" data-min-width="500">
<div class="main-col" data-min-width="400">
<div id="mainContent" class="main-row in">
<div class="main-col col-8">
<div class="cell" id="content">
@@ -95,14 +95,7 @@
$field = '';
for($i = 0; $i < $level; $i++)
{
if($i + 1 < $level)
{
$field .= '&nbsp;&nbsp;&nbsp;&nbsp;';
}
else
{
$field .= '&nbsp;&nbsp;∟&nbsp;&nbsp;';
}
$field .= '&nbsp;&nbsp;∟&nbsp;&nbsp;';
}
$field .= $data['field'];
$str .= '<td>' . $field . '</td>';
+1 -2
View File
@@ -12,7 +12,6 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::set('example', $example);?>
<?php js::set('libID', $libID);?>
<?php
js::set('typeOptions', $typeOptions);
@@ -69,7 +68,7 @@ js::set('struct_paramsType', $lang->struct->paramsType);
<tr>
<th><?php echo $lang->api->module;?></th>
<td>
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></span>
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, '', "class='form-control chosen'");?></span>
</td>
<td></td>
</tr>
-1
View File
@@ -13,7 +13,6 @@
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::import($jsRoot . 'vue/vue.js');?>
<?php js::set('example', $example);?>
<?php js::set('libID', $api->lib);?>
<?php
js::set('typeOptions', $typeOptions);
+1 -3
View File
@@ -42,10 +42,8 @@
</div>
<?php if(!$moduleTree):?>
<hr class="space">
<?php if(!$isRelease):?>
<div class="text-center text-muted tips"><?php echo $lang->api->noModule;?></div>
<?php endif;?>
<?php endif;?>
<?php echo $moduleTree;?>
</div>
</div>
@@ -73,7 +71,7 @@
</div>
</div>
<?php else:?>
<div class="cell main-col" data-min-width="400">
<div class="cell">
<div class="detail">
<ul class="list-group">
<?php foreach($apiList as $api):?>
+1 -1
View File
@@ -41,7 +41,7 @@
<td><?php echo zget($users, $release->addedBy, '');?></td>
<td class="c-date"><?php echo $release->addedDate;?></td>
<td class='c-actions'>
<?php if(common::hasPriv('api', 'deleteRelease')) echo html::a($this->createLink('api', 'deleteRelease', "libID=$libID&id=$release->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->api->deleteRelease}' class='btn'");?>
<?php echo html::a($this->createLink('api', 'deleteRelease', "libID=$libID&id=$release->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->api->delete}' class='btn'");?>
</td>
</tr>
<?php endforeach;?>
+2 -2
View File
@@ -49,8 +49,8 @@
<td class="c-date"><?php echo $struct->addedDate;?></td>
<td class='c-actions'>
<?php
if(common::hasPriv('api', 'editStruct')) echo html::a($this->createLink('api', 'editStruct', "libID=$libID&structID=$struct->id"), '<i class="icon-edit"></i>', '', "title='{$lang->api->editStruct}' class='btn'");
if(common::hasPriv('api', 'deleteStruct')) echo html::a($this->createLink('api', 'deleteStruct', "libID=$libID&structID=$struct->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->api->deleteStruct}' class='btn'");
if(common::hasPriv('api', 'editStruct')) echo html::a($this->createLink('api', 'editStruct', "libID=$libID&structID=$struct->id"), '<i class="icon-edit"></i>', '', "title='{$lang->api->edit}' class='btn'");
if(common::hasPriv('api', 'deleteStruct')) echo html::a($this->createLink('api', 'deleteStruct', "libID=$libID&structID=$struct->id"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->api->delete}' class='btn'");
?>
</td>
</tr>
+4 -4
View File
@@ -8,14 +8,14 @@ $lang->backup->restore = 'Restore';
$lang->backup->change = 'Edit Expiration';
$lang->backup->changeAB = 'Edit';
$lang->backup->rmPHPHeader = 'Remove PHP header';
$lang->backup->setting = 'Setting';
$lang->backup->setting = 'Settings';
$lang->backup->settingAction = 'Backup Setting';
$lang->backup->settingAction = 'Backup Settings';
$lang->backup->time = 'Date';
$lang->backup->files = 'Files';
$lang->backup->allCount = 'All Count';
$lang->backup->count = 'Backup Count';
$lang->backup->allCount = 'All Files';
$lang->backup->count = 'Backup Files';
$lang->backup->size = 'Size';
$lang->backup->status = 'Status';
+18 -4
View File
@@ -230,7 +230,7 @@ class block extends control
$commonField = 'common';
if($module == 'project' and $projectID)
{
$project = $this->loadModel('project')->getByID($this->session->project);
$project = $this->loadModel('project')->getByID($projectID);
$commonField = $project->model . 'common';
}
@@ -595,9 +595,15 @@ class block extends control
$this->session->set('storyList', $uri, 'product');
$this->session->set('testtaskList', $uri, 'qa');
$tasks = $this->loadModel('task')->getUserSuspendedTasks($this->app->user->account);
foreach($todos as $key => $todo)
{
if($todo->date == '2030-01-01') unset($todos[$key]);
if($todo->date == '2030-01-01')
{
unset($todos[$key]);
continue;
}
if($todo->type == 'task' and isset($tasks[$todo->idvalue])) unset($todos[$key]);
}
$this->view->todos = $todos;
@@ -886,7 +892,7 @@ class block extends control
}
$today = helper::today();
if(isset($this->config->maxVersion)) $monday = date('Ymd', strtotime($this->loadModel('weekly')->getThisMonday($today)));
$monday = date('Ymd', strtotime($this->loadModel('weekly')->getThisMonday($today)));
$tasks = $this->dao->select("project,
sum(consumed) as totalConsumed,
sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft")
@@ -906,7 +912,7 @@ class block extends control
$project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100;
$project->executions = $this->project->getStats($projectID, 'all', 0, 0, 30, 'id_desc', $pager);
}
elseif($project->model == 'waterfall' and isset($this->config->maxVersion))
elseif($project->model == 'waterfall')
{
$begin = $project->begin;
$weeks = $this->weekly->getWeekPairs($begin);
@@ -1703,6 +1709,7 @@ class block extends control
$objectCountList += array('risk' => 'riskCount', 'issue' => 'issueCount');
}
$tasks = $this->loadModel('task')->getUserSuspendedTasks($this->app->user->account);
foreach($objectCountList as $objectType => $objectCount)
{
if(!isset($hasViewPriv[$objectType])) continue;
@@ -1731,6 +1738,11 @@ class block extends control
unset($objects[$key]);
continue;
}
if($todo->type == 'task' and isset($tasks[$todo->idvalue]))
{
unset($objects[$key]);
continue;
}
$todo->begin = date::formatTime($todo->begin);
$todo->end = date::formatTime($todo->end);
@@ -1741,6 +1753,8 @@ class block extends control
{
$this->app->loadLang('task');
$this->app->loadLang('execution');
$objects = $this->loadModel('task')->getUserTasks($this->app->user->account, 'assignedTo', $limitCount);
}
if($objectType == 'bug') $this->app->loadLang('bug');
-32
View File
@@ -105,48 +105,16 @@ $lang->block->spent = 'Has Been Spent';
$lang->block->budget = 'Budget';
$lang->block->left = 'Residuals';
$lang->block->default['waterfall']['project']['1']['title'] = 'Project Weekly';
$lang->block->default['waterfall']['project']['1']['block'] = 'waterfallreport';
$lang->block->default['waterfall']['project']['1']['source'] = 'project';
$lang->block->default['waterfall']['project']['1']['grid'] = 8;
$lang->block->default['waterfall']['project']['2']['title'] = 'Estimate';
$lang->block->default['waterfall']['project']['2']['block'] = 'waterfallestimate';
$lang->block->default['waterfall']['project']['2']['source'] = 'project';
$lang->block->default['waterfall']['project']['2']['grid'] = 4;
$lang->block->default['waterfall']['project']['3']['title'] = 'Plan Gantt Chart';
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
$lang->block->default['waterfall']['project']['4']['title'] = 'Progress Chart';
$lang->block->default['waterfall']['project']['4']['block'] = 'waterfallprogress';
$lang->block->default['waterfall']['project']['4']['grid'] = 4;
$lang->block->default['waterfall']['project']['5']['title'] = 'Project Issue';
$lang->block->default['waterfall']['project']['5']['block'] = 'waterfallissue';
$lang->block->default['waterfall']['project']['5']['source'] = 'project';
$lang->block->default['waterfall']['project']['5']['grid'] = 8;
$lang->block->default['waterfall']['project']['5']['params']['type'] = 'all';
$lang->block->default['waterfall']['project']['5']['params']['count'] = '15';
$lang->block->default['waterfall']['project']['5']['params']['orderBy'] = 'id_desc';
$lang->block->default['waterfall']['project']['6']['title'] = 'Dynamic';
$lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic';
$lang->block->default['waterfall']['project']['6']['grid'] = 4;
$lang->block->default['waterfall']['project']['6']['source'] = 'project';
$lang->block->default['waterfall']['project']['7']['title'] = 'Project Risk';
$lang->block->default['waterfall']['project']['7']['block'] = 'waterfallrisk';
$lang->block->default['waterfall']['project']['7']['source'] = 'project';
$lang->block->default['waterfall']['project']['7']['grid'] = 8;
$lang->block->default['waterfall']['project']['7']['params']['type'] = 'all';
$lang->block->default['waterfall']['project']['7']['params']['count'] = '15';
$lang->block->default['waterfall']['project']['7']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['project']['1']['title'] = 'Project Overview';
$lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview';
$lang->block->default['scrum']['project']['1']['grid'] = 8;
-32
View File
@@ -105,48 +105,16 @@ $lang->block->spent = '已花费';
$lang->block->budget = '预算';
$lang->block->left = '剩余';
$lang->block->default['waterfall']['project']['1']['title'] = '项目周报';
$lang->block->default['waterfall']['project']['1']['block'] = 'waterfallreport';
$lang->block->default['waterfall']['project']['1']['source'] = 'project';
$lang->block->default['waterfall']['project']['1']['grid'] = 8;
$lang->block->default['waterfall']['project']['2']['title'] = '估算';
$lang->block->default['waterfall']['project']['2']['block'] = 'waterfallestimate';
$lang->block->default['waterfall']['project']['2']['source'] = 'project';
$lang->block->default['waterfall']['project']['2']['grid'] = 4;
$lang->block->default['waterfall']['project']['3']['title'] = "项目计划";
$lang->block->default['waterfall']['project']['3']['block'] = 'waterfallgantt';
$lang->block->default['waterfall']['project']['3']['source'] = 'project';
$lang->block->default['waterfall']['project']['3']['grid'] = 8;
$lang->block->default['waterfall']['project']['4']['title'] = '到目前为止项目进展趋势图';
$lang->block->default['waterfall']['project']['4']['block'] = 'waterfallprogress';
$lang->block->default['waterfall']['project']['4']['grid'] = 4;
$lang->block->default['waterfall']['project']['5']['title'] = '项目问题';
$lang->block->default['waterfall']['project']['5']['block'] = 'waterfallissue';
$lang->block->default['waterfall']['project']['5']['source'] = 'project';
$lang->block->default['waterfall']['project']['5']['grid'] = 8;
$lang->block->default['waterfall']['project']['5']['params']['type'] = 'all';
$lang->block->default['waterfall']['project']['5']['params']['count'] = '15';
$lang->block->default['waterfall']['project']['5']['params']['orderBy'] = 'id_desc';
$lang->block->default['waterfall']['project']['6']['title'] = '最新动态';
$lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic';
$lang->block->default['waterfall']['project']['6']['grid'] = 4;
$lang->block->default['waterfall']['project']['6']['source'] = 'project';
$lang->block->default['waterfall']['project']['7']['title'] = '项目风险';
$lang->block->default['waterfall']['project']['7']['block'] = 'waterfallrisk';
$lang->block->default['waterfall']['project']['7']['source'] = 'project';
$lang->block->default['waterfall']['project']['7']['grid'] = 8;
$lang->block->default['waterfall']['project']['7']['params']['type'] = 'all';
$lang->block->default['waterfall']['project']['7']['params']['count'] = '15';
$lang->block->default['waterfall']['project']['7']['params']['orderBy'] = 'id_desc';
$lang->block->default['scrum']['project']['1']['title'] = '项目概况';
$lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview';
$lang->block->default['scrum']['project']['1']['grid'] = 8;
+13 -1
View File
@@ -166,7 +166,19 @@ class blockModel extends model
{
$data = array();
$data['tasks'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_TASK)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->fetch('count');
$tasks = $this->dao->select('t1.id')->from(TABLE_TASK)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
->leftJoin(TABLE_PROJECT)->alias('t3')->on('t1.execution=t3.id')
->where('t1.assignedTo')->eq($this->app->user->account)
->andWhere('t2.status')->ne('suspended')
->andWhere('t3.status')->ne('suspended')
->andWhere('t2.type')->eq('project')
->andWhere('t3.type')->in('sprint,stage')
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
->andWhere('t3.deleted')->eq(0)
->fetchAll('id');
$data['tasks'] = isset($tasks) ? count($tasks) : 0;
$data['doneTasks'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_TASK)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->andWhere('status')->eq('done')->fetch('count');
$data['bugs'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_BUG)
->where('assignedTo')->eq($this->app->user->account)
+1 -1
View File
@@ -40,7 +40,7 @@ $config->bug->list->exportFields = 'id, product, branch, module, project, execut
$config->bug->list->customCreateFields = 'execution,story,task,pri,severity,os,browser,deadline,mailto,keywords';
$config->bug->list->customBatchCreateFields = 'execution,steps,type,pri,deadline,severity,os,browser,keywords';
$config->bug->list->customBatchEditFields = 'type,severity,pri,productplan,assignedTo,deadline,status,resolvedBy,resolution,os,browser,keywords';
$config->bug->list->customBatchEditFields = 'type,severity,pri,productplan,assignedTo,deadline,resolvedBy,resolution,os,browser,keywords';
$config->bug->custom = new stdclass();
$config->bug->custom->createFields = $config->bug->list->customCreateFields;
+39 -11
View File
@@ -408,15 +408,7 @@ class bug extends control
if($this->app->tab == 'execution')
{
if(!preg_match("/(m=|\/)execution(&f=|-)bug(&|-|\.)?/", $this->session->bugList))
{
$location = $this->session->bugList;
}
else
{
$executionID = $this->post->execution ? $this->post->execution : $output['executionID'];
$location = $this->createLink('execution', 'bug', "executionID=$executionID");
}
$location = $this->session->bugList ? $this->session->bugList : $this->createLink('execution', 'bug', "executionID={$output['executionID']}");
}
elseif($this->app->tab == 'project')
{
@@ -678,6 +670,9 @@ class bug extends control
}
setcookie('bugModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
/* If link from no head then reload. */
if(isonlybody()) die(js::reload('parent.parent'));
die(js::locate($this->createLink('bug', 'browse', "productID={$productID}&branch=$branch&browseType=unclosed&param=0&orderBy=id_desc"), 'parent'));
}
@@ -882,6 +877,7 @@ class bug extends control
}
}
}
if(isonlybody()) die(js::reload('parent.parent'));
die(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
}
@@ -969,7 +965,7 @@ class bug extends control
$this->view->productID = $productID;
$this->view->product = $product;
$this->view->productName = $this->products[$productID];
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, $bug->branch);
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, $bug->branch, '', true);
$this->view->projects = array(0 => '') + $this->product->getProjectPairsByProduct($productID, $bug->branch, $bug->project);
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $bug->branch);
$this->view->currentModuleID = $currentModuleID;
@@ -995,6 +991,11 @@ class bug extends control
*/
public function batchEdit($productID = 0, $branch = 0)
{
if($this->app->tab == 'product')
{
$this->product->setMenu($productID);
}
if($this->post->titles)
{
$allChanges = $this->bug->batchUpdate();
@@ -1035,7 +1036,7 @@ class bug extends control
$branchProduct = $product->type == 'normal' ? false : true;
/* Set plans. */
$plans = $this->loadModel('productplan')->getPairs($productID, $branch);
$plans = $this->loadModel('productplan')->getPairs($productID, $branch, '', true);
$plans = array('' => '', 'ditto' => $this->lang->bug->ditto) + $plans;
/* Set branches and modules. */
@@ -1257,6 +1258,33 @@ class bug extends control
die(js::locate($this->session->bugList, 'parent'));
}
/**
* Batch change the plan of bug.
*
* @param int $planID
* @access public
* @return void
*/
public function batchChangePlan($planID)
{
if($this->post->bugIDList)
{
$bugIDList = $this->post->bugIDList;
$bugIDList = array_unique($bugIDList);
unset($_POST['bugIDList']);
$allChanges = $this->bug->batchChangePlan($bugIDList, $planID);
if(dao::isError()) die(js::error(dao::getError()));
foreach($allChanges as $bugID => $changes)
{
$this->loadModel('action');
$actionID = $this->action->create('bug', $bugID, 'Edited');
$this->action->logHistory($actionID, $changes);
}
}
$this->loadModel('score')->create('ajax', 'batchOther');
die(js::locate($this->session->bugList, 'parent'));
}
/**
* Batch update assign of bug.
*
+2
View File
@@ -1,3 +1,5 @@
#importLinesModal .modal-dialog {width: 80%;}
.c-id {width: 50px !important;}
.c-branch, .c-module, .c-os {width: 120px;}
.c-execution {width: 130px;}
+1
View File
@@ -46,3 +46,4 @@ html[lang='en'] #deadlineTd .input-group-addon {padding: 5px 18px;}
#osBox {width: 190px;}
#projectBox .required:after {right: 1px;}
#branch_chosen {min-width: 90px;}
#notifyEmailTd .input-group-addon, #deadlineTd .input-group-addon {border-radius: 2px 0px 2px 0px !important;}
+10 -1
View File
@@ -1,7 +1,16 @@
.main-actions {display: none;}
#main {margin-bottom: 40px;}
#main {margin-bottom: 40px; min-width: unset;}
#mainMenu .pull-left>a {display: none;}
#mainMenu .pull-left .divider {display: none;}
#mainMenu .pull-right {display: none;}
#mainContent .col-4 {display: none;}
.modal-dialog {width: 90%;}
#mainMenu {position: fixed; width: 100%; z-index: 999;}
#scrollContent {margin-top: 35px; height: calc(100% - 70px); display: block; overflow: hidden;}
#scrollContent:hover{overflow: overlay;}
html, body, #main, .container { height: 100%;}
body * {font-size: 13px !important; line-height: 1.42857143; color: rgb(51, 51, 51);}
.page-title > .label-id {min-width: 25px; line-height: 13px;}
::-webkit-scrollbar {width: 10px; height: 10px;}
::-webkit-scrollbar-thumb:vertical {box-shadow: inset 1px 1px 0 rgb(0 0 0 / 10%), inset 0 -1px 0 rgb(0 0 0 / 7%); background-color: rgba(0, 0, 0, 0.2); border-radius: 10px; opacity: 0; transition: opacity 0.1s;}
.btn span{line-height: 16px; vertical-align: middle;}
+10
View File
@@ -662,4 +662,14 @@ function setBranchRelated(branchID, productID, num)
}
setOpenedBuilds(buildLink, num);
}
if(config.currentMethod == 'batchedit')
{
planID = $('#plans' + num).val();
planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&branch=' + branchID + '&planID=' + planID + '&fieldID=' + num + '&needCreate=false&expired=&param=skipParent');
$('#plans' + num).parent('td').load(planLink, function()
{
$('#plans' + num).chosen();
});
}
}
+9 -3
View File
@@ -28,8 +28,14 @@ $(function()
xuanAction += "<a href='" + url + "'" + title + target + btnClass + '>' + action + "</a>";
});
xuanAction += '</div>';
$('body').append(xuanAction);
if(xuanAction != "<div class='xuancard-actions fixed'>")
{
xuanAction += '</div>';
$('body').append(xuanAction);
}
else
{
$('#scrollContent').css('height', 'calc(100% - 36px)');
}
$('.xuancard-actions a.iframe').modalTrigger();
})
+6 -3
View File
@@ -41,13 +41,15 @@ $lang->bug->steps = 'Repro Steps';
$lang->bug->status = 'Status';
$lang->bug->statusAB = 'Status';
$lang->bug->subStatus = 'Sub Status';
$lang->bug->activatedCount = 'Activated Times';
$lang->bug->activatedCount = 'Activation';
$lang->bug->activatedCountAB = 'Active';
$lang->bug->activatedDate = 'ActivatedDate';
$lang->bug->confirmed = 'Confirmed';
$lang->bug->confirmedAB = 'C';
$lang->bug->toTask = 'Convert to Task';
$lang->bug->toStory = 'Convert to Story';
$lang->bug->feedbackBy = 'From Name';
$lang->bug->notifyEmail = 'From Email';
$lang->bug->mailto = 'Mailto';
$lang->bug->openedBy = 'ReportedBy';
$lang->bug->openedByAB = 'Reporter';
@@ -63,8 +65,8 @@ $lang->bug->resolvedByAB = 'ResolvedBy';
$lang->bug->resolution = 'Resolution';
$lang->bug->resolutionAB = 'Resolution';
$lang->bug->resolvedBuild = 'Build';
$lang->bug->resolvedDate = 'Resolved Date';
$lang->bug->resolvedDateAB = 'ResolvedDate';
$lang->bug->resolvedDate = 'Resolved';
$lang->bug->resolvedDateAB = 'Resolved';
$lang->bug->deadline = 'Deadline';
$lang->bug->deadlineAB = 'Deadline';
$lang->bug->plan = 'Plan';
@@ -99,6 +101,7 @@ $lang->bug->edit = 'Edit Bug';
$lang->bug->batchEdit = 'Batch Edit';
$lang->bug->batchChangeModule = 'Batch Edit Modules';
$lang->bug->batchChangeBranch = 'Batch Edit Branches';
$lang->bug->batchChangePlan = 'Batch Edit Plans';
$lang->bug->batchClose = 'Batch Close';
$lang->bug->assignTo = 'Assign';
$lang->bug->assignAction = 'Assign Bug';
+6 -2
View File
@@ -48,6 +48,8 @@ $lang->bug->confirmed = '是否确认';
$lang->bug->confirmedAB = '确认';
$lang->bug->toTask = '转任务';
$lang->bug->toStory = "转{$lang->SRCommon}";
$lang->bug->feedbackBy = '反馈者';
$lang->bug->notifyEmail = '通知邮箱';
$lang->bug->mailto = '抄送给';
$lang->bug->openedBy = '由谁创建';
$lang->bug->openedByAB = '创建者';
@@ -99,6 +101,7 @@ $lang->bug->edit = '编辑Bug';
$lang->bug->batchEdit = '批量编辑';
$lang->bug->batchChangeModule = '批量修改模块';
$lang->bug->batchChangeBranch = '批量修改分支';
$lang->bug->batchChangePlan = '批量修改计划';
$lang->bug->batchClose = '批量关闭';
$lang->bug->assignTo = '指派';
$lang->bug->assignAction = '指派Bug';
@@ -278,8 +281,9 @@ $lang->bug->statusList['active'] = '激活';
$lang->bug->statusList['resolved'] = '已解决';
$lang->bug->statusList['closed'] = '已关闭';
$lang->bug->confirmedList[1] = '是';
$lang->bug->confirmedList[0] = '否';
$lang->bug->confirmedList[''] = '';
$lang->bug->confirmedList[1] = '是';
$lang->bug->confirmedList[0] = '否';
$lang->bug->resolutionList[''] = '';
$lang->bug->resolutionList['bydesign'] = '设计如此';
+61 -14
View File
@@ -85,7 +85,12 @@ class bugModel extends model
/* Use classic mode to replace required project. */
if($this->config->systemMode == 'classic' and strpos($this->config->bug->create->requiredFields, 'project') !== false) $this->config->bug->create->requiredFields = str_replace('project', 'execution', $this->config->bug->create->requiredFields);
$this->dao->insert(TABLE_BUG)->data($bug)->autoCheck()->batchCheck($this->config->bug->create->requiredFields, 'notempty')->exec();
$this->dao->insert(TABLE_BUG)->data($bug)
->autoCheck()
->checkIF($bug->notifyEmail, 'notifyEmail', 'email')
->batchCheck($this->config->bug->create->requiredFields, 'notempty')
->exec();
if(!dao::isError())
{
$bugID = $this->dao->lastInsertID();
@@ -94,6 +99,8 @@ class bugModel extends model
$this->file->saveUpload('bug', $bugID);
empty($bug->case) ? $this->loadModel('score')->create('bug', 'create', $bugID) : $this->loadModel('score')->create('bug', 'createFormCase', $bug->case);
if($bug->execution) $this->loadModel('kanban')->updateLane($bug->execution, 'bug');
/* Callback the callable method to process the related data for object that is transfered to bug. */
if($from && is_callable(array($this, $this->config->bug->fromObjects[$from]['callback']))) call_user_func(array($this, $this->config->bug->fromObjects[$from]['callback']), $bugID);
@@ -249,6 +256,7 @@ class bugModel extends model
$bugID = $this->dao->lastInsertID();
$this->executeHooks($bugID);
if($bug->execution) $this->loadModel('kanban')->updateLane($bug->execution, 'bug');
/* When the bug is created by uploading the image, add the image to the file of the bug. */
$this->loadModel('score')->create('bug', 'create', $bugID);
@@ -661,6 +669,7 @@ class bugModel extends model
->batchCheck($this->config->bug->edit->requiredFields, 'notempty')
->checkIF($bug->resolvedBy, 'resolution', 'notempty')
->checkIF($bug->closedBy, 'resolution', 'notempty')
->checkIF($bug->notifyEmail, 'notifyEmail', 'email')
->checkIF($bug->resolution == 'duplicate', 'duplicateBug', 'notempty')
->checkIF($bug->resolution == 'fixed', 'resolvedBuild','notempty')
->where('id')->eq((int)$bugID)
@@ -678,6 +687,8 @@ class bugModel extends model
if(!empty($bug->resolvedBy)) $this->loadModel('score')->create('bug', 'resolve', $bugID);
$this->file->updateObjectID($this->post->uid, $bugID, 'bug');
if($bug->execution and $bug->status != $oldBug->status) $this->loadModel('kanban')->updateLane($bug->execution, 'bug');
return common::createChanges($oldBug, $bug);
}
}
@@ -917,6 +928,7 @@ class bugModel extends model
if(!dao::isError())
{
$this->loadModel('score')->create('bug', 'confirmBug', $oldBug);
if($oldBug->execution) $this->loadModel('kanban')->updateLane($oldBug->execution, 'bug');
return common::createChanges($oldBug, $bug);
}
}
@@ -1029,6 +1041,7 @@ class bugModel extends model
if(!dao::isError())
{
$this->loadModel('score')->create('bug', 'resolve', $oldBug);
if($oldBug->execution) $this->loadModel('kanban')->updateLane($oldBug->execution, 'bug');
/* Link bug to build and release. */
$this->linkBugToBuild($bugID, $bug->resolvedBuild);
@@ -1096,6 +1109,35 @@ class bugModel extends model
return $allChanges;
}
/**
* Batch change the plan of bug.
*
* @param array $bugIDList
* @param int $planID
* @access public
* @return array
*/
public function batchChangePlan($bugIDList, $planID)
{
$now = helper::now();
$allChanges = array();
$oldBugs = $this->getByList($bugIDList);
foreach($bugIDList as $bugID)
{
$oldBug = $oldBugs[$bugID];
if($planID == $oldBug->plan) continue;
$bug = new stdclass();
$bug->lastEditedBy = $this->app->user->account;
$bug->lastEditedDate = $now;
$bug->plan = $planID;
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->where('id')->eq((int)$bugID)->exec();
if(!dao::isError()) $allChanges[$bugID] = common::createChanges($oldBug, $bug);
}
return $allChanges;
}
/**
* Batch resolve bugs.
*
@@ -1161,6 +1203,7 @@ class bugModel extends model
$this->dao->update(TABLE_BUG)->data($bug)->where('id')->eq($bugID)->exec();
$this->executeHooks($bugID);
if($oldBug->execution) $this->loadModel('kanban')->updateLane($oldBug->execution, 'bug');
$changes[$bugID] = common::createChanges($oldBug, $bug);
}
@@ -1179,7 +1222,12 @@ class bugModel extends model
*/
public function activate($bugID)
{
$oldBug = $this->getById($bugID);
$bugID = (int)$bugID;
$oldBug = $this->getById($bugID);
$solveBuild = $this->dao->select('id')
->from(TABLE_BUILD)
->where("CONCAT(',', bugs, ',')")->like("%,{$bugID},%")
->fetch('id');
$now = helper::now();
$bug = fixer::input('post')
->setDefault('assignedTo', $oldBug->resolvedBy)
@@ -1205,19 +1253,15 @@ class bugModel extends model
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->where('id')->eq((int)$bugID)->exec();
$this->dao->update(TABLE_BUG)->set('activatedCount = activatedCount + 1')->where('id')->eq((int)$bugID)->exec();
$openedBuilds = explode(',', $oldBug->openedBuild);
if($openedBuilds)
if($solveBuild)
{
$this->loadModel('build');
foreach($openedBuilds as $openedBuild)
{
$build = $this->build->getByID($openedBuild);
if(empty($build)) continue;
$build->bugs = trim(str_replace(",$bugID,", ',', ",$build->bugs,"), ',');
$this->dao->update(TABLE_BUILD)->set('bugs')->eq($build->bugs)->where('id')->eq((int)$openedBuild)->exec();
}
$build = $this->build->getByID($solveBuild);
$build->bugs = trim(str_replace(",$bugID,", ',', ",$build->bugs,"), ',');
$this->dao->update(TABLE_BUILD)->set('bugs')->eq($build->bugs)->where('id')->eq((int)$solveBuild)->exec();
}
if($oldBug->execution) $this->loadModel('kanban')->updateLane($oldBug->execution, 'bug');
$bug->activatedCount += 1;
return common::createChanges($oldBug, $bug);
}
@@ -1246,6 +1290,7 @@ class bugModel extends model
->get();
$this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->where('id')->eq((int)$bugID)->exec();
if($oldBug->execution) $this->loadModel('kanban')->updateLane($oldBug->execution, 'bug');
return common::createChanges($oldBug, $bug);
}
@@ -1583,7 +1628,9 @@ class bugModel extends model
->beginIF($type == 'noclosed')->andWhere('status')->ne('closed')->fi()
->beginIF($build)->andWhere("CONCAT(',', openedBuild, ',') like '%,$build,%'")->fi()
->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug');
@@ -1602,7 +1649,7 @@ class bugModel extends model
* @access public
* @return array
*/
public function getProductLeftBugs($build, $productID, $branch = 0, $linkedBugs = '', $pager = null)
public function getProductLeftBugs($build, $productID, $branch = '', $linkedBugs = '', $pager = null)
{
$build = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq($build)->fetch();
if(empty($build->execution)) return array();
@@ -1625,7 +1672,7 @@ class bugModel extends model
->andWhere("(status = 'active' OR resolvedDate > '{$execution->end}')")
->andWhere('openedBuild')->notin($beforeBuilds)
->beginIF($linkedBugs)->andWhere('id')->notIN($linkedBugs)->fi()
->beginIF($branch)->andWhere('branch')->in("0,$branch")->fi()
->beginIF($branch !== '')->andWhere('branch')->in("0,$branch")->fi()
->page($pager)
->fetchAll();
+1 -3
View File
@@ -59,7 +59,6 @@
<th class='c-plan<?php echo zget($visibleFields, 'productplan', ' hidden') . zget($requiredFields, 'productplan', '', ' required');?>'><?php echo $lang->bug->productplan;?></th>
<th class='c-assigned<?php echo zget($visibleFields, 'assignedTo', ' hidden') . zget($requiredFields, 'assignedTo', '', ' required');?>'><?php echo $lang->bug->assignedTo;?></th>
<th class='c-date<?php echo zget($visibleFields, 'deadline', ' hidden') . zget($requiredFields, 'deadline', '', ' required');?>'><?php echo $lang->bug->deadline;?></th>
<th class='c-status<?php echo zget($visibleFields, 'status', ' hidden')?>'><?php echo $lang->bug->status;?></th>
<th class='c-os<?php echo zget($visibleFields, 'os', ' hidden') . zget($requiredFields, 'os', '', ' required');?>'><?php echo $lang->bug->os;?></th>
<th class='c-browser<?php echo zget($visibleFields, 'browser', ' hidden') . zget($requiredFields, 'browser', '', ' required');?>'><?php echo $lang->bug->browser;?></th>
<th class='c-keywords<?php echo zget($visibleFields, 'keywords', ' hidden') . zget($requiredFields, 'keywords', '', ' required');?>'><?php echo $lang->bug->keywords;?></th>
@@ -119,7 +118,6 @@
<td class='<?php echo zget($visibleFields, 'productplan', ' hidden')?>' style='overflow:visible'><?php echo html::select("plans[$bugID]", $plans, $bug->plan, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'assignedTo', ' hidden')?>' style='overflow:visible'><?php echo html::select("assignedTos[$bugID]", $users, $bug->assignedTo, "class='form-control chosen'");?></td>
<td class='<?php echo zget($visibleFields, 'deadline', ' hidden')?>' style='overflow:visible'><?php echo html::input("deadlines[$bugID]", $bug->deadline, "class='form-control form-date'");?></td>
<td <?php echo zget($visibleFields, 'status', "class='hidden'")?>><?php echo html::select("statuses[$bugID]", $statusList, $bug->status, 'class=form-control');?></td>
<td <?php echo zget($visibleFields, 'os', "class='hidden'")?>><?php echo html::select("os[$bugID]", $osList, $bug->os, 'class=form-control');?></td>
<td <?php echo zget($visibleFields, 'browser', "class='hidden'")?>><?php echo html::select("browsers[$bugID]", $browserList, $bug->browser, 'class=form-control');?></td>
<td <?php echo zget($visibleFields, 'keywords', "class='hidden'")?>><?php echo html::input("keywords[$bugID]", $bug->keywords, 'class=form-control');?></td>
@@ -143,7 +141,7 @@
<tr>
<td colspan='<?php echo $branchProduct ? $columns : ($columns - 1);?>' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php echo html::backButton();?>
<?php echo $this->app->tab == 'product' ? html::a($this->session->bugList, $lang->goback, '', "class='btn btn-back btn-wide'") : html::backButton();?>
</td>
</tr>
</tfoot>
+20
View File
@@ -146,6 +146,26 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
</div>
</td>
</tr>
<tr>
<th><nobr><?php echo $lang->bug->feedbackBy;?></nobr></th>
<td><?php echo html::input('feedbackBy', '', "class='form-control'");?></td>
<td id='notifyEmailTd'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->bug->notifyEmail?></span>
<span><?php echo html::input('notifyEmail', '', "class='form-control'");?></span>
</div>
</td>
</tr>
<?php else:?>
<td>
<div class='input-group' id='feedback'>
<span class="input-group-addon"><?php echo $lang->bug->feedbackBy?></span>
<?php echo html::input('feedbackBy', '', "class='form-control'");?>
<span class="input-group-addon"><?php echo $lang->bug->notifyEmail?></span>
<?php echo html::input('notifyEmail', '', "class='form-control'");?>
</div>
</td>
</tr>
<?php endif;?>
<?php if($showExecution):?>
<?php $showOS = strpos(",$showFields,", ',os,') !== false;?>
+9 -1
View File
@@ -137,7 +137,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</tr>
<tr>
<th><?php echo $lang->bug->status;?></th>
<td><?php echo html::select('status', $lang->bug->statusList, $bug->status, "class='form-control chosen'");?></td>
<td><?php echo zget($lang->bug->statusList, $bug->status);?></td>
</tr>
<tr>
<th><?php echo $lang->bug->confirmed;?></th>
@@ -151,6 +151,14 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
<th><?php echo $lang->bug->deadline;?></th>
<td><?php echo html::input('deadline', $bug->deadline, "class='form-control form-date'");?></td>
</tr>
<tr>
<th><?php echo $lang->bug->feedbackBy;?></th>
<td><?php echo html::input('feedbackBy', $bug->feedbackBy, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->bug->notifyEmail;?></th>
<td><?php echo html::input('notifyEmail', $bug->notifyEmail, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->bug->os;?></th>
<td><?php echo html::select('os', $lang->bug->osList, $bug->os, "class='form-control chosen'");?></td>
+23 -3
View File
@@ -37,6 +37,9 @@
</div>
<?php endif;?>
</div>
<?php if($this->app->getViewType() == 'xhtml'):?>
<div id="scrollContent">
<?php endif;?>
<div id="mainContent" class="main-row">
<div class="main-col col-8">
<div class="cell">
@@ -65,7 +68,9 @@
?>
</div>
<?php $this->printExtendFields($bug, 'div', "position=left&inForm=0&inCell=1");?>
<div class='cell'><?php include '../../common/view/action.html.php';?></div>
<?php if($this->app->getViewType() != 'xhtml'):?>
<div class="cell"><?php include '../../common/view/action.html.php';?></div>
<?php endif;?>
<?php
$params = "bugID=$bug->id";
$extraParams = "extras=bugID=$bug->id";
@@ -88,7 +93,7 @@
if($this->app->tab != 'product')
{
common::printIcon('bug', 'toStory', "product=$bug->product&branch=$bug->branch&module=0&story=0&execution=0&bugID=$bug->id", $bug, 'button', $lang->icons['story'], '', '', '', "data-app='product'", $lang->bug->toStory);
common::printIcon('bug', 'toStory', "product=$bug->product&branch=$bug->branch&module=0&story=0&execution=0&bugID=$bug->id", $bug, 'button', $lang->icons['story'], '', '', '', "data-app='" . $this->app->tab . "'", $lang->bug->toStory);
common::printIcon('bug', 'createCase', $convertParams, $bug, 'button', 'sitemap');
}
@@ -223,6 +228,14 @@
?>
</td>
</tr>
<tr>
<th><?php echo $lang->bug->feedbackBy;?></th>
<td><?php echo $bug->feedbackBy;?></td>
</tr>
<tr>
<th><?php echo $lang->bug->notifyEmail;?></th>
<td><?php echo $bug->notifyEmail;?></td>
</tr>
<tr>
<th><?php echo $lang->bug->os;?></th>
<td><?php echo $lang->bug->osList[$bug->os];?></td>
@@ -300,7 +313,11 @@
if($bug->openedBuild)
{
$openedBuilds = explode(',', $bug->openedBuild);
foreach($openedBuilds as $openedBuild) isset($builds[$openedBuild]) ? print($builds[$openedBuild] . '<br />') : print($openedBuild . '<br />');
foreach($openedBuilds as $openedBuild)
{
if(!$openedBuild) continue;
isset($builds[$openedBuild]) ? print($builds[$openedBuild] . '<br />') : print($openedBuild . '<br />');
}
}
else
{
@@ -394,6 +411,9 @@
<?php $this->printExtendFields($bug, 'div', "position=right&inForm=0&inCell=1");?>
</div>
</div>
<?php if($this->app->getViewType() == 'xhtml'):?>
</div>
<?php endif;?>
<div id="mainActions" class='main-actions'>
<?php common::printPreAndNext($preAndNext);?>
-1
View File
@@ -54,7 +54,6 @@ class ciModel extends model
*/
public function syncCompileStatus($compile)
{
/* Max retry times is: 3. */
if($compile->times >= 3)
{
$this->dao->update(TABLE_COMPILE)->set('status')->eq('failure')->where('id')->eq($compile->id)->exec();
+4
View File
@@ -4,11 +4,15 @@ $lang->index = new stdclass();
$lang->my = new stdclass();
$lang->todo = new stdclass();
$lang->program = new stdclass();
$lang->programplan = new stdclass();
$lang->product = new stdclass();
$lang->project = new stdclass();
$lang->design = new stdclass();
$lang->stage = new stdclass();
$lang->scrum = new stdclass();
$lang->waterfall = new stdclass();
$lang->execution = new stdclass();
$lang->kanban = new stdclass();
$lang->story = new stdclass();
$lang->release = new stdclass();
$lang->branch = new stdclass();
+73 -62
View File
@@ -45,34 +45,38 @@ $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 = 'Reset';
$lang->cancel = 'Cancel';
$lang->refresh = 'Refresh';
$lang->edit = 'Edit';
$lang->delete = 'Delete';
$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->reset = 'Reset';
$lang->cancel = 'Cancel';
$lang->refresh = 'Refresh';
$lang->create = 'Create';
$lang->edit = 'Edit';
$lang->delete = 'Delete';
$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 = 'Global Setting';
$lang->waterfallModel = 'Waterfall';
$lang->all = 'All';
$lang->actions = 'Action';
$lang->restore = 'Reset';
@@ -137,6 +141,7 @@ $lang->program->common = 'Program';
$lang->product->common = 'Product';
$lang->project->common = 'Project';
$lang->execution->common = $config->systemMode == 'new' ? 'Execution' : $lang->executionCommon;
$lang->kanban->common = 'Kanban';
$lang->qa->common = 'QA';
$lang->devops->common = 'DevOps';
$lang->doc->common = 'Doc';
@@ -161,6 +166,13 @@ $lang->dept->common = 'Dept';
$lang->upgrade->common = 'Update';
$lang->program->list = 'Program List';
$lang->program->kanban = 'Program Kanban';
$lang->design->common = 'Design';
$lang->design->HLDS = 'HLDS';
$lang->design->DDS = 'DDS';
$lang->design->DBDS = 'DBDS';
$lang->design->ADS = 'ADS';
$lang->stage->common = 'Stage';
$lang->stage->list = 'Stage List';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->personnel->common = 'Member';
@@ -179,38 +191,37 @@ $lang->score->shortCommon = 'Score';
$lang->testreport->shortCommon = 'Report';
$lang->qa->shortCommon = 'QA';
$lang->dashboard = 'Dashboard';
$lang->contribute = 'Contribute';
$lang->dynamic = 'Dynamic';
$lang->contact = 'Contacts';
$lang->whitelist = 'Whitelist';
$lang->roadmap = 'Roadmap';
$lang->track = 'Track';
$lang->settings = 'Settings';
$lang->overview = 'Overview';
$lang->module = 'Module';
$lang->priv = 'Privilege';
$lang->design = 'Design';
$lang->other = 'Other';
$lang->estimation = 'Estimation';
$lang->issue = 'Issue';
$lang->risk = 'Risk';
$lang->measure = 'Report';
$lang->treeView = 'Tree View';
$lang->groupView = 'Group View';
$lang->kanban = 'Kanban';
$lang->burn = 'Burndown';
$lang->view = 'View';
$lang->intro = 'Introduction';
$lang->indexPage = 'Index';
$lang->model = 'Model';
$lang->redev = 'Develop';
$lang->browser = 'Browser';
$lang->db = 'Database';
$lang->editor = 'Editor';
$lang->timezone = 'Timezone';
$lang->security = 'Security';
$lang->calendar = 'Calendar';
$lang->dashboard = 'Dashboard';
$lang->contribute = 'Contribute';
$lang->dynamic = 'Dynamic';
$lang->contact = 'Contacts';
$lang->whitelist = 'Whitelist';
$lang->roadmap = 'Roadmap';
$lang->track = 'Track';
$lang->settings = 'Settings';
$lang->overview = 'Overview';
$lang->module = 'Module';
$lang->priv = 'Privilege';
$lang->other = 'Other';
$lang->estimation = 'Estimation';
$lang->issue = 'Issue';
$lang->risk = 'Risk';
$lang->measure = 'Report';
$lang->treeView = 'Tree View';
$lang->groupView = 'Group View';
$lang->executionKanban = 'Kanban';
$lang->burn = 'Burndown';
$lang->view = 'View';
$lang->intro = 'Introduction';
$lang->indexPage = 'Index';
$lang->model = 'Model';
$lang->redev = 'Develop';
$lang->browser = 'Browser';
$lang->db = 'Database';
$lang->editor = 'Editor';
$lang->timezone = 'Timezone';
$lang->security = 'Security';
$lang->calendar = 'Calendar';
$lang->my->work = 'Work';
@@ -229,8 +240,8 @@ $lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'Doc';
$lang->doc->apiStruct = 'Struct';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->product->list = $lang->productCommon . ' List';
$lang->product->kanban = $lang->productCommon . ' Kanban';
+69 -12
View File
@@ -155,7 +155,7 @@ $lang->product->menu = new stdclass();
$lang->product->menu->dashboard = array('link' => "{$lang->dashboard}|product|dashboard|productID=%s");
if($config->URAndSR) $lang->product->menu->requirement = array('link' => "$lang->URCommon|product|browse|productID=%s&branch=&browseType=unclosed&param=0&storyType=requirement", 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->story = array('link' => "$lang->SRCommon|product|browse|productID=%s", 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->plan = array('link' => "{$lang->productplan->shortCommon}|productplan|browse|productID=%s", 'subModule' => 'productplan');
$lang->product->menu->plan = array('link' => "{$lang->productplan->shortCommon}|productplan|browse|productID=%s", 'subModule' => 'productplan,bug');
$lang->product->menu->release = array('link' => "{$lang->release->common}|release|browse|productID=%s", 'subModule' => 'release');
$lang->product->menu->roadmap = array('link' => "{$lang->roadmap}|product|roadmap|productID=%s");
if($config->systemMode == 'new') $lang->product->menu->project = array('link' => "{$lang->project->common}|product|project|status=all&productID=%s");
@@ -239,6 +239,52 @@ $lang->scrum->menu->settings['subMenu']->whitelist = array('link' => "{$lang->
$lang->scrum->menu->settings['subMenu']->stakeholder = array('link' => "{$lang->stakeholder->common}|stakeholder|browse|project=%s", 'subModule' => 'stakeholder');
$lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang->priv}|project|group|project=%s", 'alias' => 'group,manageview,managepriv');
/* Waterfall menu. */
$lang->waterfall->menu = new stdclass();
$lang->waterfall->menu->index = array('link' => "$lang->dashboard|project|index|project=%s");
$lang->waterfall->menu->programplan = array('link' => "{$lang->productplan->shortCommon}|programplan|browse|project=%s&productID=0&type=lists", 'subModule' => 'programplan');
$lang->waterfall->menu->execution = array('link' => "{$lang->stage->common}|project|execution|status=all&projectID=%s");
$lang->waterfall->menu->story = array('link' => "$lang->SRCommon|projectstory|story|project=%s", 'subModule' => 'projectstory,tree', 'exclude' => 'projectstory-track');
$lang->waterfall->menu->design = array('link' => "{$lang->design->common}|design|browse|project=%s");
$lang->waterfall->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug', 'alias' => 'bug,testtask,testcase');
$lang->waterfall->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->waterfall->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s");
$lang->waterfall->menu->release = array('link' => "{$lang->release->common}|projectrelease|browse|project=%s", 'subModule' => 'projectrelease');
$lang->waterfall->menu->dynamic = array('link' => "$lang->dynamic|project|dynamic|project=%s");
$lang->waterfall->menu->settings = $lang->scrum->menu->settings;
$lang->waterfall->dividerMenu = ',programplan,build,dynamic,';
/* Waterfall menu order. */
$lang->waterfall->menuOrder[5] = 'index';
$lang->waterfall->menuOrder[15] = 'programplan';
$lang->waterfall->menuOrder[20] = 'execution';
$lang->waterfall->menuOrder[25] = 'story';
$lang->waterfall->menuOrder[30] = 'design';
$lang->waterfall->menuOrder[35] = 'devops';
$lang->waterfall->menuOrder[55] = 'qa';
$lang->waterfall->menuOrder[60] = 'doc';
$lang->waterfall->menuOrder[65] = 'build';
$lang->waterfall->menuOrder[70] = 'release';
$lang->waterfall->menuOrder[80] = 'dynamic';
$lang->waterfall->menu->doc['subMenu'] = new stdclass();
$lang->waterfall->menu->programplan['subMenu'] = new stdclass();
$lang->waterfall->menu->programplan['subMenu']->lists = array('link' => "{$lang->stage->list}|programplan|browse|projectID=%s&productID=0&type=lists", 'alias' => 'create');
$lang->waterfall->menu->qa['subMenu'] = new stdclass();
$lang->waterfall->menu->qa['subMenu']->bug = array('link' => "{$lang->bug->common}|project|bug|projectID=%s", 'subModule' => 'bug');
$lang->waterfall->menu->qa['subMenu']->testcase = array('link' => "{$lang->testcase->shortCommon}|project|testcase|projectID=%s", 'subModule' => 'testsuite,testcase,caselib,tree');
$lang->waterfall->menu->qa['subMenu']->testtask = array('link' => "{$lang->testtask->common}|project|testtask|projectID=%s", 'subModule' => 'testtask', 'class' => 'dropdown dropdown-hover');
$lang->waterfall->menu->design['subMenu'] = new stdclass();
$lang->waterfall->menu->design['subMenu']->all = array('link' => "$lang->all|design|browse|projectID=%s&productID=0&browseType=all");
$lang->waterfall->menu->design['subMenu']->hlds = array('link' => "{$lang->design->HLDS}|design|browse|projectID=%s&productID=0&browseType=HLDS");
$lang->waterfall->menu->design['subMenu']->dds = array('link' => "{$lang->design->DDS}|design|browse|projectID=%s&productID=0&browseType=DDS");
$lang->waterfall->menu->design['subMenu']->dbds = array('link' => "{$lang->design->DBDS}|design|browse|projectID=%s&productID=0&browseType=DBDS");
$lang->waterfall->menu->design['subMenu']->ads = array('link' => "{$lang->design->ADS}|design|browse|projectID=%s&productID=0&browseType=ADS");
$lang->waterfall->menu->design['subMenu']->bysearch = array('link' => '<a href="javascript:;" class="querybox-toggle"><i class="icon-search icon"></i> ' . $lang->searchAB . '</a>');
/* Execution menu. */
$lang->execution->homeMenu = new stdclass();
@@ -247,7 +293,7 @@ if($config->systemMode == 'new') $lang->execution->homeMenu->executionkanban = a
$lang->execution->menu = new stdclass();
$lang->execution->menu->task = array('link' => "{$lang->task->common}|execution|task|executionID=%s", 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
$lang->execution->menu->kanban = array('link' => "$lang->kanban|execution|kanban|executionID=%s");
$lang->execution->menu->kanban = array('link' => "$lang->executionKanban|execution|kanban|executionID=%s");
$lang->execution->menu->burn = array('link' => "$lang->burn|execution|burn|executionID=%s");
$lang->execution->menu->view = array('link' => "$lang->view|execution|grouptask|executionID=%s", 'alias' => 'grouptask,tree,taskeffort,gantt,calendar,relation,maintainrelation');
$lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'batchcreate,linkstory,storykanban');
@@ -415,13 +461,24 @@ $lang->company->menuOrder[30] = 'addUser';
$lang->admin->menu = new stdclass();
$lang->admin->menu->index = array('link' => "$lang->indexPage|admin|index", 'alias' => 'register,certifytemail,certifyztmobile,ztcompany');
$lang->admin->menu->company = array('link' => "{$lang->personnel->common}|company|browse|", 'subModule' => ',user,dept,group,');
$lang->admin->menu->model = array('link' => "$lang->model|custom|browsestoryconcept|", 'subModule' => 'holiday');
$lang->admin->menu->model = array('link' => "$lang->model|custom|browsestoryconcept|", 'class' => 'dropdown dropdown-hover', 'exclude' => 'custom-index,custom-set,custom-product,custom-execution,custom-required,custom-flow,custom-score,custom-feedback,custom-timezone,custom-mode');
$lang->admin->menu->custom = array('link' => "{$lang->custom->common}|custom|index", 'exclude' => 'custom-browsestoryconcept,custom-timezone,custom-estimate');
$lang->admin->menu->extension = array('link' => "{$lang->extension->common}|extension|browse", 'subModule' => 'extension');
$lang->admin->menu->dev = array('link' => "$lang->redev|dev|api", 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->message = array('link' => "{$lang->message->common}|message|index", 'subModule' => 'message,mail,webhook');
$lang->admin->menu->system = array('link' => "{$lang->admin->system}|backup|index", 'subModule' => 'cron,backup,action,admin,search', 'exclude' => 'admin-index,admin-xuanxuan,admin-register,admin-ztcompany');
$lang->admin->menu->model['dropMenu'] = new stdclass();
$lang->admin->menu->model['dropMenu']->allModel = array('link' => "{$lang->globalSetting}|custom|browsestoryconcept|", 'subModule' => 'measurement,report,sqlbuilder,subject,custom,meetingroom,baseline');
$lang->admin->menu->model['dropMenu']->waterfall = array('link' => "{$lang->waterfallModel}|stage|setType|", 'subModule' => 'stage,auditcl,cmcl,process,activity,zoutput,classify,reviewcl,reviewsetting');
$lang->admin->menu->allModel['subMenu'] = new stdclass();
$lang->admin->menu->allModel['subMenu']->storyConcept = array('link' => "{$lang->storyConcept}|custom|browsestoryconcept|");
$lang->admin->menu->allModel['menuOrder'][5] = 'storyConcept';
$lang->admin->menu->waterfall['subMenu'] = new stdclass();
$lang->admin->menu->waterfall['subMenu']->stage = array('link' => '阶段|stage|setType|', 'subModule' => 'stage');
/* Admin menu order. */
$lang->admin->menuOrder[5] = 'index';
$lang->admin->menuOrder[10] = 'company';
@@ -432,11 +489,6 @@ $lang->admin->menuOrder[30] = 'extension';
$lang->admin->menuOrder[35] = 'dev';
$lang->admin->menuOrder[40] = 'system';
$lang->admin->menu->model['subMenu'] = new stdclass();
$lang->admin->menu->model['subMenu']->storyConcept = array('link' => "{$lang->storyConcept}|custom|browsestoryconcept|");
$lang->admin->menu->model['menuOrder'][5] = 'storyConcept';
$lang->admin->menu->message['subMenu'] = new stdclass();
$lang->admin->menu->message['subMenu']->message = new stdclass();
$lang->admin->menu->message['subMenu']->mail = array('link' => "{$lang->mail->common}|mail|index", 'subModule' => 'mail');
@@ -507,6 +559,8 @@ $lang->navGroup->story = 'product';
$lang->navGroup->project = 'project';
$lang->navGroup->deploy = 'project';
$lang->navGroup->programplan = 'project';
$lang->navGroup->design = 'project';
$lang->navGroup->stakeholder = 'project';
$lang->navGroup->projectbuild = 'project';
@@ -522,10 +576,13 @@ $lang->navGroup->build = 'project';
$lang->navGroup->measrecord = 'project';
$lang->navGroup->milestone = 'project';
$lang->navGroup->execution = 'execution';
$lang->navGroup->task = 'execution';
$lang->navGroup->build = 'execution';
$lang->navGroup->team = 'execution';
$lang->navGroup->kanban = 'execution';
$lang->navGroup->execution = 'execution';
$lang->navGroup->task = 'execution';
$lang->navGroup->build = 'execution';
$lang->navGroup->team = 'execution';
$lang->navGroup->kanbancolumn = 'execution';
$lang->navGroup->kanbanlane = 'execution';
$lang->navGroup->doc = 'doc';
$lang->navGroup->doclib = 'doc';
+71 -60
View File
@@ -45,34 +45,38 @@ $lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar
$lang->agreement = "已阅读并同意<a href='http://zpl.pub/page/zplv12.html' target='_blank'>《Z PUBLIC LICENSE授权协议1.2》</a>。<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->edit = '编辑';
$lang->delete = '删除';
$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->reset = '重填';
$lang->cancel = '取消';
$lang->refresh = '刷新';
$lang->create = '新建';
$lang->edit = '编辑';
$lang->delete = '删除';
$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->all = '所有';
$lang->actions = '操作';
$lang->restore = '恢复默认';
@@ -141,6 +145,7 @@ $lang->program->common = '项目集';
$lang->product->common = '产品';
$lang->project->common = '项目';
$lang->execution->common = $config->systemMode == 'new' ? '执行' : $lang->executionCommon;
$lang->kanban->common = '看板';
$lang->qa->common = '测试';
$lang->devops->common = 'DevOps';
$lang->doc->common = '文档';
@@ -165,6 +170,13 @@ $lang->dept->common = '部门';
$lang->upgrade->common = '升级';
$lang->program->list = '项目集列表';
$lang->program->kanban = '项目集看板';
$lang->design->common = '设计';
$lang->design->HLDS = '概要设计';
$lang->design->DDS = '详细设计';
$lang->design->DBDS = '数据库设计';
$lang->design->ADS = '接口设计';
$lang->stage->common = '阶段';
$lang->stage->list = '阶段列表';
$lang->execution->list = "{$lang->executionCommon}列表";
$lang->personnel->common = '人员';
@@ -183,38 +195,37 @@ $lang->score->shortCommon = '积分';
$lang->testreport->shortCommon = '报告';
$lang->qa->shortCommon = 'QA';
$lang->dashboard = '仪表盘';
$lang->contribute = '贡献';
$lang->dynamic = '动态';
$lang->contact = '联系人';
$lang->whitelist = '白名单';
$lang->roadmap = '路线图';
$lang->track = '矩阵';
$lang->settings = '设置';
$lang->overview = '概况';
$lang->module = '模块';
$lang->priv = '权限';
$lang->design = '设计';
$lang->other = '其他';
$lang->estimation = '估算';
$lang->issue = '问题';
$lang->risk = '风险';
$lang->measure = '度量';
$lang->treeView = '树状图';
$lang->groupView = '分组视图';
$lang->kanban = '看板';
$lang->burn = '燃尽图';
$lang->view = '视图';
$lang->intro = '介绍';
$lang->indexPage = '首页';
$lang->model = '模型';
$lang->redev = '二次开发';
$lang->browser = '浏览器';
$lang->db = '数据库';
$lang->editor = '编辑器';
$lang->timezone = '时区';
$lang->security = '安全';
$lang->calendar = '日程';
$lang->dashboard = '仪表盘';
$lang->contribute = '贡献';
$lang->dynamic = '动态';
$lang->contact = '联系人';
$lang->whitelist = '白名单';
$lang->roadmap = '路线图';
$lang->track = '矩阵';
$lang->settings = '设置';
$lang->overview = '概况';
$lang->module = '模块';
$lang->priv = '权限';
$lang->other = '其他';
$lang->estimation = '估算';
$lang->issue = '问题';
$lang->risk = '风险';
$lang->measure = '度量';
$lang->treeView = '树状图';
$lang->groupView = '分组视图';
$lang->executionKanban = '看板';
$lang->burn = '燃尽图';
$lang->view = '视图';
$lang->intro = '介绍';
$lang->indexPage = '首页';
$lang->model = '模型';
$lang->redev = '二次开发';
$lang->browser = '浏览器';
$lang->db = '数据库';
$lang->editor = '编辑器';
$lang->timezone = '时区';
$lang->security = '安全';
$lang->calendar = '日程';
$lang->my->work = '待处理';
+31 -31
View File
@@ -179,37 +179,37 @@ $lang->score->shortCommon = '積分';
$lang->testreport->shortCommon = '報告';
$lang->qa->shortCommon = 'QA';
$lang->dashboard = '儀表盤';
$lang->contribute = '貢獻';
$lang->dynamic = '動態';
$lang->contact = '聯繫人';
$lang->whitelist = '白名單';
$lang->roadmap = '路線圖';
$lang->track = '矩陣';
$lang->settings = '設置';
$lang->overview = '概況';
$lang->module = '模組';
$lang->priv = '權限';
$lang->design = '設計';
$lang->other = '其他';
$lang->estimation = '估算';
$lang->issue = '問題';
$lang->risk = '風險';
$lang->measure = '度量';
$lang->treeView = '樹狀圖';
$lang->groupView = '分組視圖';
$lang->kanban = '看板';
$lang->burn = '燃盡圖';
$lang->view = '視圖';
$lang->intro = '介紹';
$lang->indexPage = '首頁';
$lang->model = '模型';
$lang->redev = '二次開發';
$lang->browser = '瀏覽器';
$lang->db = '資料庫';
$lang->editor = '編輯器';
$lang->timezone = '時區';
$lang->security = '安全';
$lang->dashboard = '儀表盤';
$lang->contribute = '貢獻';
$lang->dynamic = '動態';
$lang->contact = '聯繫人';
$lang->whitelist = '白名單';
$lang->roadmap = '路線圖';
$lang->track = '矩陣';
$lang->settings = '設置';
$lang->overview = '概況';
$lang->module = '模組';
$lang->priv = '權限';
$lang->design = '設計';
$lang->other = '其他';
$lang->estimation = '估算';
$lang->issue = '問題';
$lang->risk = '風險';
$lang->measure = '度量';
$lang->treeView = '樹狀圖';
$lang->groupView = '分組視圖';
$lang->executionKanban = '看板';
$lang->burn = '燃盡圖';
$lang->view = '視圖';
$lang->intro = '介紹';
$lang->indexPage = '首頁';
$lang->model = '模型';
$lang->redev = '二次開發';
$lang->browser = '瀏覽器';
$lang->db = '資料庫';
$lang->editor = '編輯器';
$lang->timezone = '時區';
$lang->security = '安全';
$lang->calendar = '日程';
$lang->my->work = '待處理';
+9 -8
View File
@@ -847,6 +847,9 @@ class commonModel extends model
$linkPart = explode('|', $menu['link']);
if(!isset($linkPart[2])) continue;
$method = $linkPart[2];
if($currentModule == 'report' and $method == 'annualData') continue; // Skip some pages that do not require permissions.
if(common::hasPriv($currentModule, $method))
{
$display = true;
@@ -2851,15 +2854,13 @@ EOD;
{
if(empty($markdown)) return false;
$markdown = str_replace('&', '&amp;', $markdown);
global $app;
$hyperdown = $app->loadClass('hyperdown');
$content = $hyperdown->makeHtml($markdown);
$content = htmlspecialchars_decode($content);
$content = fixer::stripDataTags($content);
return $content;
$app->loadClass('parsedown', true);
return parsedown::instance()
->setSafeMode(true)
->setBreaksEnabled(true)
->setMarkupEscaped(true)
->text($markdown);
}
}
+3 -4
View File
@@ -1,5 +1,5 @@
<?php $currentModule = $this->moduleName;?>
<?php $currentMethod = $this->methodName;?>
<?php $currentModule = $this->app->rawModule;?>
<?php $currentMethod = $this->app->rawMethod;?>
<?php $datatableId = $this->moduleName . ucfirst($this->methodName);?>
<style>
@@ -46,7 +46,6 @@ $(function()
var allModule = $('#showModuleModal input[name="showAllModule"]:checked').val();
var showBranch = $('#showModuleModal input[name="showBranch"]:checked').val();
if(typeof allModule === 'undefined') allModule = false;
if(typeof showBranch === 'undefined') showBranch = false;
$.ajax(
{
type: "POST",
@@ -105,7 +104,7 @@ $(function()
<td><?php echo html::radio('showAllModule', $lang->datatable->showAllModuleList, isset($config->execution->task->allModule) ? $config->execution->task->allModule : 0);?></td>
</tr>
<?php endif;?>
<?php if(!empty($product) and $product->type != 'normal' and ($this->app->tab == 'product' or $this->app->tab == 'qa')):?>
<?php if(!empty($product) and $product->type != 'normal'):?>
<tr>
<td><?php echo $lang->datatable->showBranch;?></td>
<td><?php echo html::radio('showBranch', $lang->datatable->showBranchList, isset($config->$currentModule->$currentMethod->showBranch) ? $config->$currentModule->$currentMethod->showBranch : 1);?></td>
+1 -1
View File
@@ -25,7 +25,7 @@ include 'chosen.html.php';
</div>
</div>
</div>
<?php if(isset($lang->{$app->tab}->menu->$activeMenu) and isset($lang->{$app->tab}->menu->{$activeMenu}['subMenu'])):?>
<?php if(isset($lang->{$app->tab}->menu->$activeMenu) and is_array($lang->{$app->tab}->menu->$activeMenu) and isset($lang->{$app->tab}->menu->{$activeMenu}['subMenu'])):?>
<div id='subHeader'>
<div class='container'>
<div id="pageNav" class='btn-toolbar'><?php if(isset($lang->modulePageNav)) echo $lang->modulePageNav;?></div>
+1
View File
@@ -71,6 +71,7 @@ if($extHookFiles) foreach($extHookFiles as $extHookFile) include $extHookFile;
?>
</head>
<?php $singleClass = $this->app->getViewType() == 'xhtml' ? 'allow-self-open' : '';?>
<?php if(isset($pageBodyClass)) $singleClass = $singleClass . ' ' . $pageBodyClass; ?>
<?php if($this->moduleName == 'index' && $this->methodName == 'index'): ?>
<body class='menu-<?php echo $this->cookie->hideMenu ? 'hide' : 'show'; ?> <?php echo $singleClass;?>'>
<?php else: ?>
+55 -19
View File
@@ -5,7 +5,7 @@
#kanbanList .panel-heading {padding: 10px;}
#kanbanList .panel-body {padding: 0 10px 10px;}
#kanbanList .kanban {min-height: 120px; overflow: visible;}
#kanbanList .kanban-item {margin-top: 0; border: 1px solid #ebebeb; border-radius: 2px;}
#kanbanList .kanban-item {margin-top: 0; border-radius: 2px;}
#kanbanList .kanban-item:hover {border: 1px solid #ccc;}
#kanbanList .kanban-item + .kanban-item {margin-top: 10px;}
#kanbanList .kanban-lane-items {padding: 10px; min-height: 38px;}
@@ -43,9 +43,13 @@
#kanbanList .kanban-header-col[data-type="doingProject"] + .kanban-header-col[data-type="doingExecution"] {padding: 38px 10px 0;}
#kanbanList .kanban-header-col[data-type="doingProject"]:after {content: attr(data-span-text); display: block; position: absolute; z-index: 10; left: 0; right: -100%; right: calc(-100% - 2px); top: 0; line-height: 36px; text-align: center; font-weight: bold; border-bottom: 2px solid #fff; background-color: #ededed;}
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-lane-items {height: 100%; display: flex; flex-direction: column; justify-content: center;}
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item {background-color: transparent; border: none; padding: 0; text-align: center;}
#kanbanList .kanban-item.kanban-item-span,
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item {background-color: transparent; border: none; padding: 0; text-align: center; box-shadow: none!important;}
#kanbanList .kanban-item.kanban-item-span:hover,
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item:hover {box-shadow: none;}
#kanbanList .kanban-item.kanban-item-span > .title,
#kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-item > .title {white-space: normal;}
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item > .title {display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center; height: 38px;}
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item > .title > .text {display: block; white-space: nowrap; text-overflow: clip; overflow: hidden;}
#kanbanList .kanban-col[data-type="normalRelease"] .kanban-item > .title.has-icon > .text {margin-right: 5px; max-width: calc(100% - 20px);}
@@ -55,8 +59,7 @@
#kanbanList .kanban-affixed .kanban-header-col[data-type="doingProject"]:after {background-color: #606060;}
/* Show project and execution in one row */
#kanbanList .kanban-lane-col[data-type="doingProject"] {box-shadow: 2px 0 0 #fff;}
#kanbanList .kanban-lane-col[data-type="doingProject"] + .kanban-lane-col {border-left: none;}
#kanbanList .kanban-lane-col[data-type="doingProject"] + .kanban-lane-col {border-left: none; box-shadow: inset 2px 0 0 #fff;}
#kanbanList .kanban-lane-col[data-type="doingProject"] > .kanban-lane-items {padding: 0; overflow: visible; max-height: none!important;}
#kanbanList .project-row {position: relative; width: 200%; width: calc(200% + 2px);}
#kanbanList .project-row + .project-row {border-top: 2px solid #fff;}
@@ -84,6 +87,24 @@ function isEarlierThanToday(date)
return $.zui.createDate(date).getTime() < window.todayBegin;
}
/**
* Render normal text span item
* @param {Object} item Product item object
* @param {JQuery} $item Kanban item element
* @param {Object} col Column object
* @returns {JQuery} $item Kanban item element
*/
function renderSpanItem(item, $item)
{
var $title = $item.find('.title');
if(!$title.length)
{
$title = $('<div class="title" />').appendTo($item);
}
$title.text(item.name).attr('title', item.name);
return $item.addClass('kanban-item-span');
}
/**
* Render product item
* @param {Object} item Product item object
@@ -210,6 +231,11 @@ function renderExecutionItem(item, $item)
}
$title.text(item.name).attr('title', item.name);
if(window.statusColorList && window.statusColorList[item.status])
{
$item.css('borderLeftColor', window.statusColorList[item.status]);
}
var progress = item.progress || (item.hours && !Array.isArray(item.hours) ? Math.round(item.hours.progress) : undefined);
if(progress === undefined && window.hourList)
{
@@ -301,6 +327,8 @@ function renderDoingProjectItem(item, $item)
/** All build-in columns renderers */
if(!window.columnRenderers) window.columnRenderers =
{
span: renderSpanItem,
execution: renderExecutionItem,
unclosedProduct: renderProductItem,
unexpiredPlan: renderPlanItem,
waitProject: renderProjectItem,
@@ -331,9 +359,10 @@ function addColumnRenderer(columnType, renderer)
* @param {Object} col Column object
* @returns {JQuery} $item Kanban item element
*/
function renderKanbanItem(item, $item, col)
function renderKanbanItem(item, $item, col, lane, kanban)
{
var renderer = window.columnRenderers[col.type];
var columnRenderers = window.columnRenderers;
var renderer = columnRenderers[col.cardType] || columnRenderers[col.type] || columnRenderers[lane.defaultCardType || kanban.defaultCardType];
if(renderer) return renderer(item, $item, col);
return $item;
}
@@ -365,18 +394,17 @@ function affixKanbanHeader($kanbanBoard, affixed)
*/
function updateKanbanAffixState()
{
var $boards = $('.kanban-board');
var $boards = $('.kanban-board');
var $lastAffixedBoard = $boards.filter('.kanban-affixed');
var containerTop = window.kanbanAffixContainer ? $(window.kanbanAffixContainer)[0].getBoundingClientRect().top : 0;
var $currentAffixedBoard;
var currentOffsetTop = 0;
var scrollTop = $(window).scrollTop();
$('.kanban-board').each(function()
{
var $board = $(this);
var offsetTop = $board.offset().top;
if(scrollTop >= offsetTop && offsetTop > currentOffsetTop && scrollTop < (offsetTop + $board.outerHeight() - 72))
var bounds = $board[0].getBoundingClientRect();
if(bounds.top < containerTop && bounds.bottom > (containerTop))
{
currentOffsetTop = offsetTop;
$currentAffixedBoard = $board;
}
});
@@ -397,20 +425,24 @@ $.extend($.fn.kanban.Constructor.DEFAULTS,
{
readonly: true,
maxColHeight: 260,
/* laneItemsClass: 'scrollbar-hover', */ // only show scrollbar on mouse hover
itemRender: renderKanbanItem,
useFlex: false,
showCount: false,
showCount: true,
showZeroCount: true,
onRenderHeaderCol: function($col, col)
{
if(col.type === 'doingProject') $col.attr('data-span-text', doingText);
if(col.type === 'doingProject' && window.doingText) $col.attr('data-span-text', window.doingText);
},
onRenderKanban: function($kanban, kanbanData)
{
$kanban.find('.kanban-lane-name').each(function(index)
$kanban.find('.kanban-lane').each(function(index)
{
var $lane = $(this);
if ($lane.data('lane').color) return;
var $laneName = $lane.find('.kanban-lane-name');
var color = kanbanColorList[index % kanbanColorList.length];
$(this).css('background-color', color);
$laneName.css('background-color', color);
});
/* Update project count and execution count */
@@ -422,9 +454,13 @@ $.extend($.fn.kanban.Constructor.DEFAULTS,
doingProjectCount = $doingProjectItems.find('.project-item').length;
doingExecutionCount = $doingProjectItems.find('.execution-item').length;
}
$kanban.find('.kanban-header-col[data-type="doingProject"] > .title > .count').text(doingProjectCount || 0);
$kanban.find('.kanban-header-col[data-type="doingExecution"] > .title > .count').text(doingExecutionCount || 0);
},
onCreate: function(kanban)
{
kanban.$.on('scroll', updateKanbanAffixState);
updateKanbanAffixState();
}
});
@@ -438,7 +474,7 @@ $(function()
updateKanbanAffixState();
updateTimer = null;
};
$(window).on('scroll resize', function(e)
$(window.kanbanAffixContainer || window).on('scroll resize', function(e)
{
if(updateTimer)
{
-2
View File
@@ -27,7 +27,5 @@ function submitForm(type)
$('.modal-body #insert').val(type == 'insert' ? 1 : 0);
$('#importNoticeModal .form-actions .btn').addClass('disabled');
$("button[data-target='#importNoticeModal']").closest('form').submit();
setTimeout(function(){$('#importNoticeModal .form-actions .btn').removeClass('disabled');}, 1000);
}
</script>
+5 -4
View File
@@ -167,10 +167,11 @@ class company extends control
* @param int $productID
* @param int $projectID
* @param int $executionID
* @param string $orderBy date_deac|date_asc
* @access public
* @return void
*/
public function dynamic($browseType = 'today', $param = '', $recTotal = 0, $date = '', $direction = 'next', $userID = '', $productID = 0, $projectID = 0, $executionID = 0)
public function dynamic($browseType = 'today', $param = '', $recTotal = 0, $date = '', $direction = 'next', $userID = '', $productID = 0, $projectID = 0, $executionID = 0, $orderBy = 'date_desc')
{
$this->company->setMenu();
$this->app->loadLang('user');
@@ -203,8 +204,8 @@ class company extends control
$pager = new pager($recTotal, $recPerPage = 50, $pageID = 1);
/* Append id for secend sort. */
$orderBy = $direction == 'next' ? 'date_desc' : 'date_asc';
$sort = $this->loadModel('common')->appendOrder($orderBy);
$order = $direction == 'next' ? 'date_desc' : 'date_asc';
$sort = $this->loadModel('common')->appendOrder($order);
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$date = empty($date) ? '' : date('Y-m-d', $date);
@@ -289,7 +290,7 @@ class company extends control
$this->view->userID = $userID;
$this->view->param = $param;
$this->view->browseType = $browseType;
$this->view->dateGroups = $this->action->buildDateGroup($actions, $direction, $browseType);
$this->view->dateGroups = $this->action->buildDateGroup($actions, $direction, $browseType, $orderBy);
$this->view->direction = $direction;
$this->display();
}
+2 -1
View File
@@ -18,5 +18,6 @@
.dynamic.collapsed .timeline > li + li {display: none;}
.dynamic.collapsed .dynamic-btn > .icon:before {content: '\f0d8';}
.c-user, .c-project, .c-product, .c-execution {width: 150px !important; overflow: unset;}
.c-project, .c-product, .c-execution {width: 140px !important; overflow: unset;}
.c-user,.c-order {width: 100px !important; overflow: unset;}
.c-date {width: 200px;}
+3 -2
View File
@@ -1,11 +1,12 @@
$('#account, #product, #project, #execution').change(function()
$('#account, #product, #project, #execution, #orderBy').change(function()
{
var userID = $('#account').val();
var productID = $('#product').val();
var projectID = systemMode == 'new' ? $('#project').val() : 0;
var executionID = $('#execution').val();
var orderBy = $('#orderBy').val();
browseType = browseType == 'bysearch' ? 'all' : browseType;
link = createLink('company', 'dynamic', 'browseType=' + browseType + '&param=&recTotal=0&date=&direction=next&userID=' + userID + '&productID=' + productID + '&projectID=' + projectID + '&executionID=' + executionID);
link = createLink('company', 'dynamic', 'browseType=' + browseType + '&param=&recTotal=0&date=&direction=next&userID=' + userID + '&productID=' + productID + '&projectID=' + projectID + '&executionID=' + executionID + '&orderBy=' + orderBy);
location.href = link;
})
+3
View File
@@ -37,3 +37,6 @@ $lang->company->user = 'User';
$lang->company->guestOptions[0] = 'Deny';
$lang->company->guestOptions[1] = 'Allow';
$lang->company->order['date_desc'] = 'Descending';
$lang->company->order['date_asc'] = 'Ascending';
+3
View File
@@ -37,3 +37,6 @@ $lang->company->user = '用户';
$lang->company->guestOptions[0] = '不允许';
$lang->company->guestOptions[1] = '允许';
$lang->company->order['date_desc'] = '倒序排列';
$lang->company->order['date_asc'] = '正序排列';
+4 -4
View File
@@ -24,7 +24,7 @@
$active = 'btn-active-text';
$label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";
}
echo html::a(inlink('dynamic', "browseType=$period&param=&recTotal=0&date=&direction=next&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID"), $label, '', "class='btn btn-link $active' id='{$period}'")
echo html::a(inlink('dynamic', "browseType=$period&param=&recTotal=0&date=&direction=next&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy"), $label, '', "class='btn btn-link $active' id='{$period}'")
?>
<?php endforeach;?>
<div class="input-control space c-user"><?php echo html::select('account', $userIdPairs, $userID, 'class="form-control chosen" data-max_drop_width="215"');?></div>
@@ -33,6 +33,7 @@
<div class="input-control space c-project"><?php echo html::select('project', $projects, $projectID, 'class="form-control chosen" data-max_drop_width="215"');?></div>
<?php endif;?>
<div class="input-control space c-execution"><?php echo html::select('execution', $executions, $executionID, 'class="form-control chosen" data-max_drop_width="215"'); ?></div>
<div class="input-control space c-order"><?php echo html::select('orderBy', $lang->company->order, $orderBy, 'class="form-control chosen" data-max_drop_width="215"'); ?></div>
<a class="btn btn-link querybox-toggle" id="bysearchTab"><i class="icon icon-search muted"></i> <?php echo $lang->action->dynamic->search;?></a>
</div>
</div>
@@ -52,7 +53,6 @@
<button type="button" class="btn btn-info btn-icon btn-sm dynamic-btn"><i class="icon icon-caret-down"></i></button>
</div>
<ul class="timeline timeline-tag-left <?php if($browseType == 'all') echo 'margin-l-50px';?>">
<?php if($direction == 'next') $actions = array_reverse($actions);?>
<?php foreach($actions as $i => $action):?>
<?php if(empty($firstAction)) $firstAction = $action;?>
<li <?php if($action->major) echo "class='active'";?>>
@@ -96,8 +96,8 @@ $firstDate = date('Y-m-d', strtotime($firstAction->originalDate) + 24 * 3600);
$lastDate = substr($action->originalDate, 0, 10);
$hasPre = $this->action->hasPreOrNext($firstDate, 'pre');
$hasNext = $this->action->hasPreOrNext($lastDate, 'next');
$preLink = $hasPre ? inlink('dynamic', "browseType=$browseType&param=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . '&direction=pre') : 'javascript:;';
$nextLink = $hasNext ? inlink('dynamic', "browseType=$browseType&param=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . '&direction=next') : 'javascript:;';
$preLink = $hasPre ? inlink('dynamic', "browseType=$browseType&param=$param&recTotal={$pager->recTotal}&date=" . strtotime($firstDate) . "&direction=pre&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy") : 'javascript:;';
$nextLink = $hasNext ? inlink('dynamic', "browseType=$browseType&param=$param&recTotal={$pager->recTotal}&date=" . strtotime($lastDate) . "&direction=next&userID=$userID&productID=$productID&projectID=$projectID&executionID=$executionID&orderBy=$orderBy") : 'javascript:;';
?>
<?php if($hasPre or $hasNext):?>
<div id="mainActions" class='main-actions'>
+4 -4
View File
@@ -121,7 +121,7 @@ class compileModel extends model
*/
public function exec($compile)
{
$job = $this->dao->select('t1.id,t1.name,t1.repo,t1.engine,t1.pipeline,t2.name as jenkinsName,t2.url,t2.account,t2.token,t2.password')
$job = $this->dao->select('t1.id,t1.name,t1.repo,t1.pipeline,t2.name as jenkinsName,t2.url,t2.account,t2.token,t2.password')
->from(TABLE_JOB)->alias('t1')
->leftJoin(TABLE_PIPELINE)->alias('t2')->on('t1.server=t2.id')
->where('t1.id')->eq($compile->job)
@@ -134,7 +134,7 @@ class compileModel extends model
if($job->triggerType == 'tag')
{
$lastTag = $this->loadModel('job')->getLastTagByRepo($repo);
$lastTag = $this->getLastTagByRepo($repo);
if($lastTag)
{
$job->lastTag = $lastTag;
@@ -150,8 +150,8 @@ class compileModel extends model
$this->dao->update(TABLE_COMPILE)->data($compile)->where('id')->eq($compileID)->exec();
$this->dao->update(TABLE_JOB)
->set('lastStatus')->eq($compile->status)
->set('lastExec')->eq($compile->updateDate)
->set('lastStatus')->eq($build->status)
->set('lastExec')->eq($build->updateDate)
->where('id')->eq($job->id)
->exec();
+1 -1
View File
@@ -21,7 +21,7 @@
<label class="radio-inline"><input type="radio" name="product" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="product<?php echo $key;?>"><?php echo $value;?></label>
<?php endforeach;?>
</td>
<td><span class='alert alert-info no-margin'><?php echo $lang->custom->notice->readOnlyOfProduct;?></span></td>
<td><div class='alert alert-info no-margin'><?php echo $lang->custom->notice->readOnlyOfProduct;?></div></td>
</tr>
<tr>
<th></th>
+3 -3
View File
@@ -8,11 +8,11 @@ $lang->datatable->reset = 'Reset';
$lang->datatable->custom = 'Customize Columns';
$lang->datatable->customTip = 'Check columns to display and drag columns to order.';
$lang->datatable->switchToTable = 'Switch to Common Table';
$lang->datatable->switchToDatatable = 'Switch to Advanced Table';
$lang->datatable->switchToTable = 'Common Table';
$lang->datatable->switchToDatatable = 'Advanced Table';
$lang->datatable->required = 'Required';
$lang->datatable->confirmReset = 'Do you want to restore the default settings?';
$lang->datatable->setGlobal = 'Set as Global';
$lang->datatable->setGlobal = 'Set Global';
$lang->datatable->resetGlobal = 'Global Reset';
$lang->datatable->branch = 'Branch';
+1 -1
View File
@@ -13,7 +13,7 @@ $lang->dept->common = 'Department';
$lang->dept->id = 'ID';
$lang->dept->path = 'Path';
$lang->dept->position = 'Position';
$lang->dept->manageChild = "Child Department";
$lang->dept->manageChild = "Department";
$lang->dept->edit = "Edit Department";
$lang->dept->delete = "Delete Department";
$lang->dept->parent = "Parent Dept";
+32
View File
@@ -0,0 +1,32 @@
<?php
$config->design = new stdclass();
$config->design->editor = new stdclass();
$config->design->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
$config->design->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
$config->design->editor->assignto = array('id' => 'comment', 'tools' => 'simpleTools');
$config->design->create = new stdclass();
$config->design->edit = new stdclass();
$config->design->create->requiredFields = 'name,type';
$config->design->edit->requiredFields = 'name,type';
$config->design->affectedFixedNum = 7;
global $lang;
$config->design->search['module'] = 'design';
$config->design->search['fields']['id'] = $lang->design->id;
$config->design->search['fields']['type'] = $lang->design->type;
$config->design->search['fields']['name'] = $lang->design->name;
$config->design->search['fields']['commit'] = $lang->design->submission;
$config->design->search['fields']['createdBy'] = $lang->design->createdBy;
$config->design->search['fields']['createdDate'] = $lang->design->createdDate;
$config->design->search['fields']['assignedTo'] = $lang->design->assignedTo;
$config->design->search['fields']['story'] = $lang->design->story;
$config->design->search['params']['type'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->design->typeList);
$config->design->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->design->search['params']['commit'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->design->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->design->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->design->search['params']['assignedTo'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->design->search['params']['story'] = array('operator' => '=', 'control' => 'select', 'values' => '');
+485
View File
@@ -0,0 +1,485 @@
<?php
/**
* The control file of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: control.php 5107 2020-09-02 09:46:12Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
class design extends control
{
/**
* Construct function, load module auto.
*
* @param string $moduleName
* @param string $methodName
* @access public
* @return void
*/
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
$this->loadModel('product');
$this->loadModel('project');
$this->loadModel('task');
}
/**
* Design common action.
*
* @param int $projectID
* @param int $productID
* @param int $designID
* @access public
* @return void
*/
public function commonAction($projectID = 0, $productID = 0, $designID = 0)
{
$products = $this->product->getProductPairsByProject($projectID);
$productID = $this->product->saveState($productID, $products);
$this->lang->modulePageNav = $this->design->setMenu($projectID, $products, $productID);
$this->project->setMenu($projectID);
$this->view->products = $products;
return $productID;
}
/**
* Browse designs.
*
* @param int $projectID
* @param int $productID
* @param string $type all|bySearch|HLDS|DDS|DBDS|ADS
* @param string $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function browse($projectID = 0, $productID = 0, $type = 'all', $param = '', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$productID = $this->commonAction($projectID, $productID);
/* Save session for design list and process product id. */
$this->session->set('designList', $this->app->getURI(true), 'project');
/* Build the search form. */
$queryID = ($type == 'bySearch') ? (int)$param : 0;
$actionURL = $this->createLink('design', 'browse', "projectID=$projectID&productID=$productID&type=bySearch&queryID=myQueryID");
$this->design->buildSearchForm($queryID, $actionURL);
/* Print top and right actions. */
$this->lang->TRActions = '<div class="btn-group dropdown">';
$this->lang->TRActions .= html::a(inlink('create', "projectID=$projectID&productID=$productID&type=$type"), "<i class='icon-plus'></i> {$this->lang->design->create}", '', "class='btn btn-primary'");
$this->lang->TRActions .= "<button type='button' class='btn btn-primary dropdown-toggle' data-toggle='dropdown'><span class='caret'></span>";
$this->lang->TRActions .= '</button>';
$this->lang->TRActions .= "<ul class='dropdown-menu pull-right' id='createActionMenu'>";
if(common::hasPriv('design', 'create')) $this->lang->TRActions .= '<li>' . html::a($this->createLink('design', 'create', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->create, '', "class='btn btn-link'") . '</li>';
if(common::hasPriv('design', 'batchCreate')) $this->lang->TRActions .= '<li>' . html::a($this->createLink('design', 'batchCreate', "projectID=$projectID&productID=$productID&type=$type"), $this->lang->design->batchCreate, '', "class='btn btn-link'") . '</li>';
$this->lang->TRActions .= '</ul>';
$this->lang->TRActions .= '</div>';
/* Init pager and get designs. */
$this->app->loadClass('pager', $static = true);
$pager = pager::init(0, $recPerPage, $pageID);
$designs = $this->design->getList($projectID, $productID, $type, $queryID, $orderBy, $pager);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->browse;
$this->view->position[] = $this->lang->design->browse;
$this->view->designs = $designs;
$this->view->type = $type;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->productID = $productID;
$this->view->projectID = $projectID;
$this->view->pager = $pager;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
}
/**
* Create a design.
*
* @param int $projectID
* @param int $productID
* @param string $type
* @access public
* @return void
*/
public function create($projectID = 0, $productID = 0, $type = 'all')
{
$productID = $this->commonAction($projectID, $productID);
if($_POST)
{
$designID = $this->design->create($projectID);
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
return $this->send($response);
}
$this->loadModel('action')->create('design', $designID, 'created');
$response['result'] = 'success';
$response['message'] = $this->lang->saveSuccess;
$response['locate'] = $this->createLink('design', 'browse', "projectID=$projectID&productID=$productID");
return $this->send($response);
}
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->create;
$this->view->position[] = $this->lang->design->create;
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productID);
$this->view->productID = $productID;
$this->view->type = $type;
$this->view->project = $this->loadModel('project')->getByID($projectID);
$this->display();
}
/**
* Batch create designs.
*
* @param int $projectID
* @param int $productID
* @param string $type
* @access public
* @return void
*/
public function batchCreate($projectID = 0, $productID = 0, $type = 'all')
{
$productID = $this->commonAction($projectID, $productID);
if($_POST)
{
$this->design->batchCreate($projectID, $productID);
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
return $this->send($response);
}
$response['result'] = 'success';
$response['message'] = $this->lang->saveSuccess;
$response['locate'] = inlink('browse', "projectID=$projectID&productID=$productID");
return $this->send($response);
}
$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($productID);
$this->view->users = $this->loadModel('user')->getPairs('noclosed');
$this->view->type = $type;
$this->display();
}
/**
* View a design.
*
* @param int $designID
* @access public
* @return void
*/
public function view($designID = 0)
{
$design = $this->design->getByID($designID);
$productID = $this->commonAction($design->project, $design->product, $designID);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->view;
$this->view->position[] = $this->lang->design->view;
$this->view->design = $design;
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($design->product);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->actions = $this->loadModel('action')->getList('design', $design->id);
$this->display();
}
/**
* Edit a design.
*
* @param int $designID
* @access public
* @return void
*/
public function edit($designID = 0)
{
$design = $this->design->getByID($designID);
$design = $this->design->getAffectedScope($design);
$productID = $this->commonAction($design->project, $design->product, $designID);
if($_POST)
{
$changes = $this->design->update($designID);
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
return $this->send($response);
}
if(!empty($changes))
{
$actionID = $this->loadModel('action')->create('design', $designID, 'changed');
$this->action->logHistory($actionID, $changes);
}
$response['result'] = 'success';
$response['message'] = $this->lang->saveSuccess;
$response['locate'] = $this->createLink('design', 'view', "id=$design->id");
return $this->send($response);
}
$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->stories = $this->loadModel('story')->getProductStoryPairs($design->product);
$this->display();
}
/**
* Design link commits.
*
* @param int $designID
* @param int $repoID
* @param string $begin
* @param string $end
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function linkCommit($designID = 0, $repoID = 0, $begin = '', $end = '', $recTotal = 0, $recPerPage = 50, $pageID = 1)
{
$design = $this->design->getById($designID);
$productID = $this->commonAction($design->project, $design->product, $designID);
/* Get project and date. */
$project = $this->loadModel('project')->getByID($design->project);
$begin = $begin ? date('Y-m-d', strtotime($begin)) : $project->begin;
$end = $end ? date('Y-m-d', strtotime($end)) : helper::today();
/* Get the repository information through the repoID. */
$repos = $this->loadModel('repo')->getRepoPairs($design->project);
$repoID = $repoID ? $repoID : key($repos);
if(empty($repoID)) die(js::locate(helper::createLink('repo', 'create', "objectID=$design->project")));
$repo = $this->loadModel('repo')->getRepoByID($repoID);
$revisions = $this->repo->getCommits($repo, '', 'HEAD', '', '', $begin, $end);
if($_POST)
{
$this->design->linkCommit($designID, $repoID);
$result['result'] = 'success';
$result['message'] = $this->lang->saveSuccess;
$result['locate'] = 'parent';
return $this->send($result);
}
/* Linked submission. */
$linkedRevisions = array();
$relations = $this->loadModel('common')->getRelations('design', $designID, 'commit');
foreach($relations as $relation) $linkedRevisions[$relation->BID] = $relation->BID;
foreach($revisions as $id => $commit)
{
if(isset($linkedRevisions[$commit->id])) unset($revisions[$id]);
}
/* Init pager. */
$this->app->loadClass('pager', $static = true);
$recTotal = count($revisions);
$pager = new pager($recTotal, $recPerPage, $pageID);
$revisions = array_chunk($revisions, $pager->recPerPage);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->linkCommit;
$this->view->position[] = $this->lang->design->linkCommit;
$this->view->repos = $repos;
$this->view->repoID = $repoID;
$this->view->repo = $repo;
$this->view->revisions = empty($revisions) ? $revisions : $revisions[$pageID - 1];
$this->view->designID = $designID;
$this->view->begin = $begin;
$this->view->end = $end;
$this->view->design = $this->design->getByID($designID);
$this->view->pager = $pager;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
}
/**
* Design unlink commits.
*
* @param int $designID
* @param int $commitID
* @param string $confirm
* @access public
* @return void
*/
public function unlinkCommit($designID = 0, $commitID = 0, $confirm = 'no')
{
if($confirm == 'no')
{
die(js::confirm($this->lang->design->confirmUnlink, inlink('unlinkCommit', "designID=$designID&commitID=$commitID&confirm=yes")));
}
else
{
$this->design->unlinkCommit($designID, $commitID);
die(js::reload('parent'));
}
}
/**
* View a design's commit.
*
* @param int $designID
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function viewCommit($designID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$design = $this->design->getByID($designID);
$productID = $this->commonAction($design->project, $design->product, $designID);
/* Init pager. */
$this->app->loadClass('pager', $static = true);
$pager = pager::init(0, $recPerPage, $pageID);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->submission;
$this->view->position[] = $this->lang->design->submission;
$this->view->design = $this->design->getCommit($designID, $pager);
$this->view->pager = $pager;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
}
/**
* A version of the repository.
*
* @param int $repoID
* @param int $projectID
* @access public
* @return void
*/
public function revision($repoID = 0, $projectID = 0)
{
$repo = $this->dao->select('*')->from(TABLE_REPOHISTORY)->where('id')->eq($repoID)->fetch();
$repoURL = $this->createLink('repo', 'revision', "repoID=$repo->repo&objectID=$projectID&revistion=$repo->revision");
header("location:" . $repoURL);
}
/**
* Ajax get design drop menu.
*
* @param int $projectID
* @param int $productID
* @param string $extra
* @access public
* @return void
*/
public function ajaxGetDropMenu($projectID, $productID)
{
$products = $this->loadModel('product')->getProducts($projectID);
$this->view->link = helper::createLink('design', 'browse', "projectID=$projectID&productID=%s");
$this->view->productID = $productID;
$this->view->products = $products;
$this->view->projectID = $projectID;
$this->display();
}
/**
* Delete a design.
*
* @param int $designID
* @param string $confirm
* @access public
* @return void
*/
public function delete($designID = 0, $confirm = 'no')
{
if($confirm == 'no')
{
die(js::confirm($this->lang->design->confirmDelete, inlink('delete', "designID=$designID&confirm=yes")));
}
else
{
$this->design->delete(TABLE_DESIGN, $designID);
$this->dao->delete()->from(TABLE_RELATION)->where('Atype')->eq('design')->andWhere('AID')->eq($designID)->andWhere('Btype')->eq('commit')->andwhere('relation')->eq('completedin')->exec();
$this->dao->delete()->from(TABLE_RELATION)->where('Atype')->eq('commit')->andWhere('BID')->eq($designID)->andWhere('Btype')->eq('design')->andwhere('relation')->eq('completedfrom')->exec();
die(js::locate($this->session->designList, 'parent'));
}
}
/**
* Update assign of design.
*
* @param int $designID
* @access public
* @return void
*/
public function assignTo($designID = 0)
{
if($_POST)
{
$changes = $this->design->assign($designID);
if(dao::isError()) die(js::error(dao::getError()));
$this->loadModel('action');
if(!empty($changes))
{
$actionID = $this->action->create('design', $designID, 'Assigned', $this->post->comment, $this->post->assignedTo);
$this->action->logHistory($actionID, $changes);
}
if(isonlybody()) die(js::closeModal('parent.parent', 'this'));
die(js::locate($this->createLink('design', 'browse'), 'parent'));
}
$design = $this->design->getByID($designID);
$this->view->title = $this->lang->design->common . $this->lang->colon . $this->lang->design->assignedTo;
$this->view->position[] = $this->lang->design->assignedTo;
$this->view->design = $design;
$this->view->users = $this->loadModel('project')->getTeamMemberPairs($design->project);
$this->display();
}
}
+3
View File
@@ -0,0 +1,3 @@
#featurebar {display:inline-block;}
#querybox #searchform {border-bottom: 1px solid #ddd; margin-bottom: 20px;}
#designTable td {white-space:nowrap; text-overflow:ellipsis; overflow: hidden}
+1
View File
@@ -0,0 +1 @@
.tabs .tab-pane .table{border: 1px solid #ddd; border-top: none}
+8
View File
@@ -0,0 +1,8 @@
#mainContent {min-height: 350px;}
.searchBox{min-height: 45px;}
.searchBox .srearch-date{float: left; width: 20%}
.searchBox h4{float:left;display: inline-block}
.searchBox span{float:left;line-height:30px}
#logForm .table thead th{background: #efefef}
#begin{margin-right:5px}
#end{margin-left:5px}
+4
View File
@@ -0,0 +1,4 @@
$(function()
{
$('#subNavbar .nav li[data-id=' + type.toLowerCase() + ']').addClass('active');
})
+5
View File
@@ -0,0 +1,5 @@
$(function()
{
$('#subNavbar .nav li').removeClass('active');
$('#subNavbar .nav li[data-id=' + type + ']').addClass('active');
})
+16
View File
@@ -0,0 +1,16 @@
$(document).on('click', '.ajaxPager', function()
{
$('#logBox').load($(this).attr('href'));
return false;
})
$('#product').change(function()
{
productID = $(this).val();
var link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID);
$.post(link, function(data)
{
$('#story').replaceWith(data);
$('#story_chosen').remove();
$('#story').chosen();
})
})
+4
View File
@@ -0,0 +1,4 @@
$(function()
{
$('#subNavbar .nav li[data-id=' + type.toLowerCase() + ']').addClass('active');
})
+4
View File
@@ -0,0 +1,4 @@
$(function()
{
$('#subNavbar .nav li[data-id=' + type.toLowerCase() + ']').addClass('active');
})
+28
View File
@@ -0,0 +1,28 @@
$('#begin, #end, #repo').change(function()
{
var begin = $('#begin').val();
var end = $('#end').val();
var repo = $('#repo').val();
if(begin.indexOf('-') != -1)
{
var beginarray = begin.split("-");
var begin = '';
for(i = 0; i < beginarray.length; i++) begin = begin + beginarray[i];
}
if(end.indexOf('-') != -1)
{
var endarray = end.split("-");
var end = '';
for(i = 0 ; i < endarray.length ; i++) end = end + endarray[i];
}
if(begin > end)
{
alert(errorDate);
location.href = createLink('design', 'linkCommit', "designID=" + designID + '&repoID=' + repo);
die;
}
location.href = createLink('design', 'linkCommit', "designID=" + designID + '&repoID=' + repo + '&begin=' + begin + '&end=' + end);
})
+4
View File
@@ -0,0 +1,4 @@
$(function()
{
$('#subNavbar .nav li[data-id=' + type.toLowerCase() + ']').addClass('active');
})
+78
View File
@@ -0,0 +1,78 @@
<?php
/**
* The English file of design module.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: en.php 4729 2020-09-01 07:53:55Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
/* 字段列表. */
$lang->design->id = 'ID';
$lang->design->name = 'Name';
$lang->design->story = 'Story';
$lang->design->type = 'Type';
$lang->design->ditto = 'Ditto';
$lang->design->submission = 'Commit';
$lang->design->version = 'Revision';
$lang->design->assignedTo = 'AssignedTo';
$lang->design->actions = 'Actions';
$lang->design->byQuery = 'Search';
$lang->design->products = 'Linked Product';
$lang->design->story = 'Linked Story';
$lang->design->file = 'File';
$lang->design->desc = 'Description';
$lang->design->range = 'Impact';
$lang->design->product = 'Linked Product';
$lang->design->basicInfo = 'Basic Information';
$lang->design->commitBy = 'Commit By';
$lang->design->commitDate = 'Committed Date';
$lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
$lang->design->comment = 'Comment';
/* 动作列表. */
$lang->design->common = 'Design';
$lang->design->create = 'Create Design';
$lang->design->batchCreate = 'Batch Create';
$lang->design->edit = 'Edit';
$lang->design->delete = 'Delete';
$lang->design->view = 'View';
$lang->design->browse = 'List';
$lang->design->viewCommit = 'View Commit';
$lang->design->linkCommit = 'Link Commit';
$lang->design->unlinkCommit = 'Unlink Commit';
$lang->design->submit = 'Submit Review';
$lang->design->assignTo = 'Assign';
$lang->design->revision = 'Linked Code';
/* 字段取值. */
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
$lang->design->typeList['HLDS'] = 'High-Level';
$lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';
$lang->design->featureBar['all'] = 'All';
$lang->design->featureBar += $lang->design->typeList;
/* 提示信息. */
$lang->design->errorSelection = 'No record selected!';
$lang->design->noDesign = 'No record.';
$lang->design->noCommit = 'No record commited.';
$lang->design->confirmDelete = 'Do you want to delete this design?';
$lang->design->confirmUnlink = 'Are you sure you want to remove this submission?';
$lang->design->errorDate = 'The start date can not be greater than the end date.';
$lang->design->deleted = 'Deleted';
+80
View File
@@ -0,0 +1,80 @@
<?php
/**
* The English file of design module.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: en.php 4729 2020-09-01 07:53:55Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
/* 字段列表. */
$lang->design->id = 'ID';
$lang->design->name = 'Name';
$lang->design->story = 'Story';
$lang->design->type = 'Type';
$lang->design->ditto = 'Ditto';
$lang->design->submission = 'Commit';
$lang->design->version = 'Revision';
$lang->design->assignedTo = 'AssignedTo';
$lang->design->actions = 'Actions';
$lang->design->byQuery = 'Search';
$lang->design->products = 'Linked Product';
$lang->design->story = 'Linked Story';
$lang->design->file = 'File';
$lang->design->desc = 'Description';
$lang->design->range = 'Impact';
$lang->design->product = 'Linked Product';
$lang->design->basicInfo = 'Basic Information';
$lang->design->commitBy = 'Commit By';
$lang->design->commitDate = 'Committed Date';
$lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
$lang->design->comment = 'Comment';
/* 动作列表. */
$lang->design->common = 'Design';
$lang->design->create = 'Create Design';
$lang->design->batchCreate = 'Batch Create';
$lang->design->edit = 'Edit';
$lang->design->delete = 'Delete';
$lang->design->view = 'View';
$lang->design->browse = 'List';
$lang->design->viewCommit = 'View Commit';
$lang->design->linkCommit = 'Link Commit';
$lang->design->unlinkCommit = 'Unlink Commit';
$lang->design->submit = 'Submit Review';
$lang->design->assignTo = 'Assign';
$lang->design->revision = 'Linked Code';
$lang->design->browseAction = 'Design List';
/* 字段取值. */
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
$lang->design->typeList['HLDS'] = 'High-Level';
$lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';
$lang->design->featureBar['all'] = 'All';
$lang->design->featureBar += $lang->design->typeList;
/* 提示信息. */
$lang->design->errorSelection = 'No record selected!';
$lang->design->noDesign = 'No record.';
$lang->design->noCommit = 'No record commited.';
$lang->design->confirmDelete = 'Do you want to delete this design?';
$lang->design->confirmUnlink = 'Are you sure you want to remove this submission?';
$lang->design->errorDate = 'The start date can not be greater than the end date.';
$lang->design->deleted = 'Deleted';
+78
View File
@@ -0,0 +1,78 @@
<?php
/**
* The English file of design module.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: en.php 4729 2020-09-01 07:53:55Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
/* 字段列表. */
$lang->design->id = 'ID';
$lang->design->name = 'Name';
$lang->design->story = 'Story';
$lang->design->type = 'Type';
$lang->design->ditto = 'Ditto';
$lang->design->submission = 'Commit';
$lang->design->version = 'Revision';
$lang->design->assignedTo = 'AssignedTo';
$lang->design->actions = 'Actions';
$lang->design->byQuery = 'Search';
$lang->design->products = 'Linked Product';
$lang->design->story = 'Linked Story';
$lang->design->file = 'File';
$lang->design->desc = 'Description';
$lang->design->range = 'Impact';
$lang->design->product = 'Linked Product';
$lang->design->basicInfo = 'Basic Information';
$lang->design->commitBy = 'Commit By';
$lang->design->commitDate = 'Committed Date';
$lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
$lang->design->comment = 'Comment';
/* 动作列表. */
$lang->design->common = 'Design';
$lang->design->create = 'Create Design';
$lang->design->batchCreate = 'Batch Create';
$lang->design->edit = 'Edit';
$lang->design->delete = 'Delete';
$lang->design->view = 'View';
$lang->design->browse = 'List';
$lang->design->viewCommit = 'View Commit';
$lang->design->linkCommit = 'Link Commit';
$lang->design->unlinkCommit = 'Unlink Commit';
$lang->design->submit = 'Submit Review';
$lang->design->assignTo = 'Assign';
$lang->design->revision = 'Linked Code';
/* 字段取值. */
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
$lang->design->typeList['HLDS'] = 'High-Level';
$lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';
$lang->design->featureBar['all'] = 'All';
$lang->design->featureBar += $lang->design->typeList;
/* 提示信息. */
$lang->design->errorSelection = 'No record selected!';
$lang->design->noDesign = 'No record.';
$lang->design->noCommit = 'No record commited.';
$lang->design->confirmDelete = 'Do you want to delete this design?';
$lang->design->confirmUnlink = 'Are you sure you want to remove this submission?';
$lang->design->errorDate = 'The start date can not be greater than the end date.';
$lang->design->deleted = 'Deleted';
+78
View File
@@ -0,0 +1,78 @@
<?php
/**
* The English file of design module.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: en.php 4729 2020-09-01 07:53:55Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
/* 字段列表. */
$lang->design->id = 'ID';
$lang->design->name = 'Name';
$lang->design->story = 'Story';
$lang->design->type = 'Type';
$lang->design->ditto = 'Ditto';
$lang->design->submission = 'Commit';
$lang->design->version = 'Revision';
$lang->design->assignedTo = 'AssignedTo';
$lang->design->actions = 'Actions';
$lang->design->byQuery = 'Search';
$lang->design->products = 'Linked Product';
$lang->design->story = 'Linked Story';
$lang->design->file = 'File';
$lang->design->desc = 'Description';
$lang->design->range = 'Impact';
$lang->design->product = 'Linked Product';
$lang->design->basicInfo = 'Basic Information';
$lang->design->commitBy = 'Commit By';
$lang->design->commitDate = 'Committed Date';
$lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
$lang->design->comment = 'Comment';
/* 动作列表. */
$lang->design->common = 'Design';
$lang->design->create = 'Create Design';
$lang->design->batchCreate = 'Batch Create';
$lang->design->edit = 'Edit';
$lang->design->delete = 'Delete';
$lang->design->view = 'View';
$lang->design->browse = 'List';
$lang->design->viewCommit = 'View Commit';
$lang->design->linkCommit = 'Link Commit';
$lang->design->unlinkCommit = 'Unlink Commit';
$lang->design->submit = 'Submit Review';
$lang->design->assignTo = 'Assign';
$lang->design->revision = 'Linked Code';
/* 字段取值. */
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
$lang->design->typeList['HLDS'] = 'High-Level';
$lang->design->typeList['DDS'] = 'Detailed';
$lang->design->typeList['DBDS'] = 'Database';
$lang->design->typeList['ADS'] = 'API';
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = 'All';
$lang->design->rangeList['assign'] = 'Selected';
$lang->design->featureBar['all'] = 'All';
$lang->design->featureBar += $lang->design->typeList;
/* 提示信息. */
$lang->design->errorSelection = 'No record selected!';
$lang->design->noDesign = 'No record.';
$lang->design->noCommit = 'No record commited.';
$lang->design->confirmDelete = 'Do you want to delete this design?';
$lang->design->confirmUnlink = 'Are you sure you want to remove this submission?';
$lang->design->errorDate = 'The start date can not be greater than the end date.';
$lang->design->deleted = 'Deleted';
+80
View File
@@ -0,0 +1,80 @@
<?php
/**
* The zh-cn file of design module.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: zh-cn.php 4729 2020-09-01 07:53:55Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
/* 字段列表. */
$lang->design->id = '编号';
$lang->design->name = '设计名称';
$lang->design->story = '需求';
$lang->design->type = '设计类型';
$lang->design->ditto = '同上';
$lang->design->submission = '相关提交';
$lang->design->version = '版本号';
$lang->design->assignedTo = '指派给';
$lang->design->actions = '操作';
$lang->design->byQuery = '搜索';
$lang->design->products = '所属产品';
$lang->design->story = '相关需求';
$lang->design->file = '附件';
$lang->design->desc = '设计描述';
$lang->design->range = '影响范围';
$lang->design->product = '所属产品';
$lang->design->basicInfo = '基础信息';
$lang->design->commitBy = '由谁提交';
$lang->design->commitDate = '提交时间';
$lang->design->affectedStory = "影响{$lang->SRCommon}";
$lang->design->affectedTasks = '影响任务';
$lang->design->reviewObject = '评审对象';
$lang->design->createdBy = '由谁创建';
$lang->design->createdDate = '创建时间';
$lang->design->basicInfo = '基本信息';
$lang->design->noAssigned = '未指派';
$lang->design->comment = '注释';
/* 动作列表. */
$lang->design->common = '设计';
$lang->design->create = '创建设计';
$lang->design->batchCreate = '批量创建';
$lang->design->edit = '变更';
$lang->design->delete = '删除';
$lang->design->view = '设计概况';
$lang->design->browse = '浏览列表';
$lang->design->viewCommit = '查看提交';
$lang->design->linkCommit = '关联提交';
$lang->design->unlinkCommit = '取消关联';
$lang->design->submit = '提交评审';
$lang->design->assignTo = '指派';
$lang->design->revision = '查看关联代码';
$lang->design->browseAction = '设计列表';
/* 字段取值. */
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
$lang->design->typeList['HLDS'] = '概要设计';
$lang->design->typeList['DDS'] = '详细设计';
$lang->design->typeList['DBDS'] = '数据库设计';
$lang->design->typeList['ADS'] = '接口设计';
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = '全部记录';
$lang->design->rangeList['assign'] = '选中记录';
$lang->design->featureBar['all'] = '所有';
$lang->design->featureBar += $lang->design->typeList;
/* 提示信息. */
$lang->design->errorSelection = '还没有选中记录!';
$lang->design->noDesign = '暂时没有记录';
$lang->design->noCommit = '暂时没有提交记录';
$lang->design->confirmDelete = '您确定要删除这个设计吗?';
$lang->design->confirmUnlink = '您确定要移除这个提交吗?';
$lang->design->errorDate = '开始日期不能大于结束日期';
$lang->design->deleted = '已删除';
+78
View File
@@ -0,0 +1,78 @@
<?php
/**
* The zh-tw file of design module.
*
* @copyright Copyright 2009-2020 青島易軟天創網絡科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: zh-tw.php 4729 2020-09-01 07:53:55Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
/* 欄位列表. */
$lang->design->id = '編號';
$lang->design->name = '設計名稱';
$lang->design->story = '需求';
$lang->design->type = '設計類型';
$lang->design->ditto = '同上';
$lang->design->submission = '相關提交';
$lang->design->version = '版本號';
$lang->design->assignedTo = '指派給';
$lang->design->actions = '操作';
$lang->design->byQuery = '搜索';
$lang->design->products = '所屬產品';
$lang->design->story = '相關需求';
$lang->design->file = '附件';
$lang->design->desc = '設計描述';
$lang->design->range = '影響範圍';
$lang->design->product = '所屬產品';
$lang->design->basicInfo = '基礎信息';
$lang->design->commitBy = '由誰提交';
$lang->design->commitDate = '提交時間';
$lang->design->affectedStory = "影響{$lang->SRCommon}";
$lang->design->affectedTasks = '影響任務';
$lang->design->reviewObject = '評審對象';
$lang->design->createdBy = '由誰創建';
$lang->design->createdDate = '創建時間';
$lang->design->basicInfo = '基本信息';
$lang->design->noAssigned = '未指派';
$lang->design->comment = '註釋';
/* 動作列表. */
$lang->design->common = '設計';
$lang->design->create = '創建設計';
$lang->design->batchCreate = '批量創建';
$lang->design->edit = '變更';
$lang->design->delete = '刪除';
$lang->design->view = '設計概況';
$lang->design->browse = '瀏覽列表';
$lang->design->viewCommit = '查看提交';
$lang->design->linkCommit = '關聯提交';
$lang->design->unlinkCommit = '取消關聯';
$lang->design->submit = '提交評審';
$lang->design->assignTo = '指派';
$lang->design->revision = '查看關聯代碼';
/* 欄位取值. */
$lang->design->typeList = array();
$lang->design->typeList[''] = '';
$lang->design->typeList['HLDS'] = '概要設計';
$lang->design->typeList['DDS'] = '詳細設計';
$lang->design->typeList['DBDS'] = '資料庫設計';
$lang->design->typeList['ADS'] = '介面設計';
$lang->design->rangeList = array();
$lang->design->rangeList['all'] = '全部記錄';
$lang->design->rangeList['assign'] = '選中記錄';
$lang->design->featureBar['all'] = '所有';
$lang->design->featureBar += $lang->design->typeList;
/* 提示信息. */
$lang->design->errorSelection = '還沒有選中記錄!';
$lang->design->noDesign = '暫時沒有記錄';
$lang->design->noCommit = '暫時沒有提交記錄';
$lang->design->confirmDelete = '您確定要刪除這個設計嗎?';
$lang->design->confirmUnlink = '您確定要移除這個提交嗎?';
$lang->design->errorDate = '開始日期不能大於結束日期';
$lang->design->deleted = '已刪除';
+465
View File
@@ -0,0 +1,465 @@
<?php
/**
* The model file of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: model.php 5107 2020-09-02 09:46:12Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php
class designModel extends model
{
/**
* Create a design.
*
* @param int $projectID
* @access public
* @return void
*/
public function create($projectID)
{
$design = fixer::input('post')
->stripTags('desc', $this->config->allowedTags)
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
->add('project', $projectID)
->add('version', 1)
->remove('files,labels')
->get();
$design = $this->loadModel('file')->processImgURL($design, 'desc', $this->post->uid);
$this->dao->insert(TABLE_DESIGN)->data($design)
->autoCheck()
->batchCheck($this->config->design->create->requiredFields, 'notempty')
->exec();
if(!dao::isError())
{
$designID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $designID, 'design');
$files = $this->file->saveUpload('design', $designID);
$spec = new stdclass();
$spec->design = $designID;
$spec->version = 1;
$spec->name = $design->name;
$spec->desc = $design->desc;
$spec->files = empty($files) ? '' : implode(',', array_keys($files));
$this->dao->insert(TABLE_DESIGNSPEC)->data($spec)->exec();
return $designID;
}
return false;
}
/**
* Batch create designs.
*
* @param int $projectID
* @param int $productID
* @access public
* @return bool
*/
public function batchCreate($projectID = 0, $productID = 0)
{
$data = fixer::input('post')->get();
$this->loadModel('action');
foreach($data->name as $i => $name)
{
if(!trim($name)) continue;
$design = new stdclass();
$design->story = isset($data->story[$i]) ? $data->story[$i] : '';
$design->type = $data->type[$i];
$design->name = $name;
$design->product = $productID;
$design->project = $projectID;
$design->createdBy = $this->app->user->account;
$design->createdDate = helper::now();
$this->dao->insert(TABLE_DESIGN)->data($design)->autoCheck()->batchCheck($this->config->design->create->requiredFields, 'notempty')->exec();
$designID = $this->dao->lastInsertID();
$this->action->create('design', $designID, 'Opened');
}
return true;
}
/**
* Update a design.
*
* @param int $designID
* @access public
* @return bool
*/
public function update($designID = 0)
{
$oldDesign = $this->getByID($designID);
$design = fixer::input('post')
->add('editedBy', $this->app->user->account)
->add('editedDate', helper::now())
->stripTags($this->config->design->editor->edit['id'], $this->config->allowedTags)
->remove('file,files,labels,children,toList')
->get();
$design = $this->loadModel('file')->processImgURL($design, 'desc', $this->post->uid);
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->batchCheck('name,type', 'notempty')->where('id')->eq($designID)->exec();
if(!dao::isError())
{
$this->file->updateObjectID($this->post->uid, $designID, 'design');
$files = $this->file->saveUpload('design', $designID);
$designChanged = ($oldDesign->name != $design->name || $oldDesign->desc != $design->desc || !empty($files));
if($designChanged)
{
$design = $this->getByID($designID);
$version = $design->version + 1;
$spec = new stdclass();
$spec->design = $designID;
$spec->version = $version;
$spec->name = $design->name;
$spec->desc = $design->desc;
$spec->files = empty($files) ? '' : implode(',', array_keys($files));
$this->dao->insert(TABLE_DESIGNSPEC)->data($spec)->exec();
$this->dao->update(TABLE_DESIGN)->set('version')->eq($version)->where('id')->eq($designID)->exec();
}
return common::createChanges($oldDesign, $design);
}
return false;
}
/**
* Assign a design.
*
* @param int $designID
* @access public
* @return array|bool
*/
public function assign($designID = 0)
{
$oldDesign = $this->getByID($designID);
$design = fixer::input('post')
->add('editedBy', $this->app->user->account)
->add('editedDate', helper::today())
->setDefault('assignedDate', helper::today())
->stripTags($this->config->design->editor->assignto['id'], $this->config->allowedTags)
->remove('uid,comment,files,label')
->get();
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->where('id')->eq((int)$designID)->exec();
if(!dao::isError()) return common::createChanges($oldDesign, $design);
return false;
}
/**
* LinkCommit a design.
*
* @param int $designID
* @param int $repoID
* @access public
* @return void
*/
public function linkCommit($designID = 0, $repoID = 0)
{
$revisions = $_POST['revision'];
foreach($revisions as $revision)
{
$data = new stdclass();
$data->project = $this->session->project;
$data->product = $this->session->product;
$data->AType = 'design';
$data->AID = $designID;
$data->BType = 'commit';
$data->BID = $revision;
$data->relation = 'completedin';
$data->extra = $repoID;
$this->dao->replace(TABLE_RELATION)->data($data)->autoCheck()->exec();
$data->AType = 'commit';
$data->AID = $revision;
$data->BType = 'design';
$data->BID = $designID;
$data->relation = 'completedfrom';
$this->dao->replace(TABLE_RELATION)->data($data)->autoCheck()->exec();
}
$oldCommit = $this->dao->findByID($designID)->from(TABLE_DESIGN)->fetch('commit');
$revisions = join(',', $revisions);
$commit = $oldCommit ? $oldCommit . ',' . $revisions : $revisions;
$design = new stdclass();
$design->commit = $commit;
$design->commitedBy = $this->app->user->account;
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->where('id')->eq($designID)->exec();
}
/**
* Unlink commit.
*
* @param int $designID
* @param int $commitID
* @access public
* @return void
*/
public function unlinkCommit($designID = 0, $commitID = 0)
{
/* Delete data in the zt_relation.*/
$this->dao->delete()->from(TABLE_RELATION)->where('AType')->eq('design')->andwhere('AID')->eq($designID)->andwhere('BType')->eq('commit')->andwhere('relation')->eq('completedin')->andWhere('BID')->eq($commitID)->exec();
$this->dao->delete()->from(TABLE_RELATION)->where('AType')->eq('commit')->andwhere('BID')->eq($designID)->andwhere('BType')->eq('design')->andwhere('relation')->eq('completedfrom')->andWhere('AID')->eq($commitID)->exec();
/* Commit after unlinking. */
$commit = $this->dao->select('BID')->from(TABLE_RELATION)->where('AType')->eq('design')->andWhere('AID')->eq($designID)->andWhere('BType')->eq('commit')->andwhere('relation')->eq('completedin')->fetchAll('BID');
$commit = implode(",", array_keys($commit));
$this->dao->update(TABLE_DESIGN)->set('commit')->eq($commit)->where('id')->eq($designID)->exec();
}
/**
* Get a design by id.
*
* @param int $designID
* @access public
* @return object
*/
public function getByID($designID = 0)
{
$design = $this->dao->select('*')->from(TABLE_DESIGN)->where('id')->eq($designID)->fetch();
if(!$design) return false;
$design->files = $this->loadModel('file')->getByObject('design', $designID);
$design->productName = $this->dao->findByID($design->product)->from(TABLE_PRODUCT)->fetch('name');
$design->commit = '';
$relations = $this->loadModel('common')->getRelations('design', $designID, 'commit');
foreach($relations as $relation) $design->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID&projectID={$design->project}"), "#$relation->BID", '_blank');
return $this->loadModel('file')->replaceImgURL($design, 'desc');
}
/**
* Get design pairs.
*
* @param int $productID
* @param string $type all|HLDS|DDS|DBDS|ADS
* @access public
* @return object
*/
public function getPairs($productID = 0, $type = 'all')
{
$designs = $this->dao->select('id, name')->from(TABLE_DESIGN)
->where('product')->eq($productID)
->andWhere('deleted')->eq(0)
->andWhere('type')->eq($type)
->fetchPairs();
foreach($designs as $id => $name) $designs[$id] = $id . ':' . $name;
return $designs;
}
/**
* Get affected scope.
*
* @param int $design
* @access public
* @return object
*/
public function getAffectedScope($design = 0)
{
/* Get affected tasks. */
$design->tasks = $this->dao->select('*')->from(TABLE_TASK)
->where('deleted')->eq(0)
->andWhere('status')->ne('closed')
->andWhere('design')->eq($design->id)
->orderBy('id desc')->fetchAll();
return $design;
}
/**
* Get design list.
*
* @param int $productID
* @param int $projectID
* @param string $type all|bySearch|HLDS|DDS|DBDS|ADS
* @param int $param
* @param string $orderBy
* @param int $pager
* @access public
* @return array
*/
public function getList($projectID = 0, $productID = 0, $type = 'all', $param = 0, $orderBy = 'id_desc', $pager = null)
{
if($type == 'bySearch')
{
$designs = $this->getBySearch($projectID, $productID, $param, $orderBy, $pager);
}
else
{
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
->where('deleted')->eq(0)
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->beginIF($type != 'all')->andWhere('type')->in($type)->fi()
->andWhere('product')->eq($productID)
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
return $designs;
}
/**
* Get commit.
*
* @param int $designID
* @param int $pager
* @access public
* @return object
*/
public function getCommit($designID = 0, $pager = null)
{
$design = $this->dao->select('*')->from(TABLE_DESIGN)->where('id')->eq($designID)->fetch();
$design->commit = $this->dao->select('*')->from(TABLE_REPOHISTORY)->where('id')->in($design->commit)->page($pager)->fetchAll('id');
return $design;
}
/**
* Get designs by search.
*
* @param int $projectID
* @param int $productID
* @param int $queryID
* @param string $orderBy
* @param int $pager
* @access public
* @return object
*/
public function getBySearch($projectID = 0, $productID = 0, $queryID = 0, $orderBy = 'id_desc', $pager = null)
{
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set('designQuery', $query->sql);
$this->session->set('designForm', $query->form);
}
else
{
$this->session->set('designQuery', ' 1 = 1');
}
}
else
{
if($this->session->designQuery == false) $this->session->set('designQuery', ' 1 = 1');
}
$designQuery = $this->session->designQuery;
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
->where($designQuery)
->andWhere('deleted')->eq('0')
->andWhere('project')->eq($projectID)
->andWhere('product')->eq($productID)
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
return $designs;
}
/**
* Set design menu.
*
* @param int $projectID
* @param int $products
* @param int $productID
* @param string $currentModule
* @param string $currentMethod
* @param string $extra
* @param int $branch
* @access public
* @return void
*/
public function setMenu($projectID = 0, $products, $productID = 0)
{
if($this->app->rawMethod != 'browse') unset($this->lang->waterfall->menu->design['subMenu']->bysearch);
if(empty($products) || !$productID) return '';
$currentProduct = $this->loadModel('product')->getById($productID);
setCookie("lastProduct", $productID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
$output = '';
if(!empty($products))
{
$dropMenuLink = helper::createLink('design', 'ajaxGetDropMenu', "projectID=$projectID&productID=$productID");
$output = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem' title='{$currentProduct->name}'><span class='text'>{$currentProduct->name}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div></div>";
}
return $output;
}
/**
* Build search form.
*
* @param int $queryID
* @param string $actionURL
* @access public
* @return void
*/
public function buildSearchForm($queryID = 0, $actionURL = '')
{
$this->config->design->search['actionURL'] = $actionURL;
$this->config->design->search['queryID'] = $queryID;
$this->loadModel('search')->setSearchParams($this->config->design->search);
}
/**
* Print assignedTo html.
*
* @param object $design
* @param array $users
* @access public
* @return string
*/
public function printAssignedHtml($design = '', $users = '')
{
$btnTextClass = '';
$assignedToText = zget($users, $design->assignedTo);
if(empty($design->assignedTo))
{
$btnTextClass = 'text-primary';
$assignedToText = $this->lang->design->noAssigned;
}
if($design->assignedTo == $this->app->user->account) $btnTextClass = 'text-red';
$btnClass = $design->assignedTo == 'closed' ? ' disabled' : '';
$btnClass = "iframe btn btn-icon-left btn-sm {$btnClass}";
$assignToLink = helper::createLink('design', 'assignTo', "designID=$design->id", '', true);
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span title='" . zget($users, $design->assignedTo) . "' class='{$btnTextClass}'>{$assignedToText}</span>", '', "class='$btnClass'");
echo !common::hasPriv('design', 'assignTo', $design) ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
}
}
@@ -0,0 +1,64 @@
<?php js::set('productID', $productID);?>
<?php
$iCharges = 0;
$others = 0;
$closeds = 0;
$tab = 'project';
$productNames = array();
foreach($products as $product)
{
if($product->status == 'normal' and $product->PO == $this->app->user->account) $iCharges++;
if($product->status == 'normal' and !($product->PO == $this->app->user->account)) $others++;
if($product->status == 'closed') $closeds++;
$productNames[] = $product->name;
}
$productsPinYin = common::convert2Pinyin($productNames);
$myProductsHtml = '';
$normalProductsHtml = '';
$closedProductsHtml = '';
foreach($products as $product)
{
$selected = $product->id == $productID ? 'selected' : '';
$productName = $product->name;
$linkHtml = sprintf($link, $product->id);
if($product->status == 'normal' and $product->PO == $this->app->user->account)
{
$myProductsHtml .= html::a($linkHtml, $productName, '', "class='text-important $selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='$tab'");
}
else if($product->status == 'normal' and !($product->PO == $this->app->user->account))
{
$normalProductsHtml .= html::a($linkHtml, $productName, '', "class='$selected' title='{$productName}' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='$tab'");
}
else if($product->status == 'closed')
{
$closedProductsHtml .= html::a($linkHtml, $productName, '', "class='$selected' title='{$productName}' class='closed' data-key='" . zget($productsPinYin, $product->name, '') . "' data-app='$tab'");
}
}
?>
<div class="table-row">
<div class="table-col col-left">
<div class='list-group'>
<?php
if(!empty($myProductsHtml))
{
echo "<div class='heading'>{$lang->product->mine}</div>";
echo $myProductsHtml;
if(!empty($myProductsHtml))
{
echo "<div class='heading'>{$lang->product->other}</div>";
}
}
echo $normalProductsHtml;
?>
</div>
<div class="col-footer">
<a class='pull-right toggle-right-col not-list-item'><?php echo $lang->product->closed?><i class='icon icon-angle-right'></i></a>
</div>
</div>
<div class="table-col col-right">
<div class='list-group'><?php echo $closedProductsHtml;?></div>
</div>
</div>
<script>scrollToSelected();</script>
+40
View File
@@ -0,0 +1,40 @@
<?php
/**
* The assignTo of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: assignto.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include "../../common/view/header.html.php";?>
<?php include '../../common/view/kindeditor.html.php';?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<h2>
<span class='prefix label-id'><strong><?php echo $design->id;?></strong></span>
<?php echo "<span title='$design->name'>" . $design->name . '</span>';?>
</h2>
</div>
<form class='load-indicator main-form' method='post' target='hiddenwin'>
<table class='table table-form'>
<tbody>
<tr>
<th class='w-100px'><?php echo $lang->design->assignedTo;?></th>
<td><?php echo html::select('assignedTo', $users, $design->assignedTo, "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->comment;?></th>
<td colspan='2'><?php echo html::textarea('comment', '', "rows='6' class='form-control kindeditor' hidefocus='true'");?></td>
</tr>
<tr>
<td class='text-center form-actions' colspan='3'><?php echo html::submitButton(); ?></td> </tr>
</tbody>
</table>
</form>
</div>
<?php include "../../common/view/footer.html.php";?>
+45
View File
@@ -0,0 +1,45 @@
<?php
/**
* The batchCreate view of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: batchcreate.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('type', $type);?>
<div id="mainContent" class="main-content fade">
<div class="main-header"><h2><?php echo $lang->design->batchCreate;?></h2></div>
<form class="load-indicator main-form form-ajax" method='post' enctype='multipart/form-data' id='dataform'>
<table class="table table-form">
<thead>
<tr>
<th class='w-50px'><?php echo $lang->design->id;?></th>
<th class='w-200px'><?php echo $lang->design->story;?></th>
<th class='w-200px required'><?php echo $lang->design->type;?></th>
<th class='required'><?php echo $lang->design->name;?></th>
</tr>
</thead>
<tbody>
<?php for($i = 1; $i <= 10; $i ++):?>
<tr>
<td><?php echo $i;?></td>
<td><?php echo html::select("story[$i]", $stories, '', "class='form-control chosen'");?></td>
<td><?php echo html::select("type[$i]", $lang->design->typeList, '', "class='form-control chosen'");?></td>
<td><?php echo html::input("name[$i]", '', "class='form-control'");?></td>
</tr>
<?php endfor;?>
<tr>
<td colspan='4' class='form-actions text-center'>
<?php echo html::submitButton() . html::backButton();?>
</td>
</tr>
</tbody>
</table>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+69
View File
@@ -0,0 +1,69 @@
<?php
/**
* The browse view file of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: browse.html.php 5102 2020-09-03 10:59:54Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/sortable.html.php';?>
<?php js::set('type', strtolower($type));?>
<style>
.btn-group a i.icon-plus {font-size: 16px;}
.btn-group a.btn-primary {border-right: 1px solid rgba(255,255,255,0.3);}
.btn-group button.dropdown-toggle.btn-primary {padding:6px;}
</style>
<div class="cell<?php if($type == 'bySearch') echo ' show';?>" id="queryBox" data-module='design'></div>
<div id="mainContent" class="main-table">
<?php if(empty($designs)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->design->noDesign;?></span></p>
</div>
<?php else:?>
<form id='designFrom' method='post' class="main-table">
<table class='table has-sort-head table-fixrd' id="designTable">
<?php $vars = "projectID=$projectID&productID=$productID&type=$type&param=$param&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<thead>
<tr>
<th class="text-left w-60px"> <?php common::printOrderLink('id', $orderBy, $vars, $lang->design->id);?></th>
<th class="text-left w-100px"> <?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?></th>
<th class="text-left"> <?php common::printOrderLink('name', $orderBy, $vars, $lang->design->name);?></th>
<th class="text-left w-120px"> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdBy);?></th>
<th class="text-left w-150px"> <?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?></th>
<th class="c-assignedTo w-120px"><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->design->assignedTo);?></th>
<th class="text-center w-100px"> <?php echo $lang->design->actions;?></th>
</tr>
</thead>
<tbody>
<?php foreach($designs as $design):?>
<tr>
<td calss="c-id"> <?php printf('%03d', $design->id);?></td>
<td class="c-type"> <?php echo zget($lang->design->typeList, $design->type);?></td>
<td class="c-name" title="<?php echo $design->name;?>"><?php echo html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name);?></td>
<td class="c-createdBy"> <?php echo zget($users, $design->createdBy);?></td>
<td class="c-createdDate"><?php echo substr($design->createdDate, 0, 11);?></td>
<td class="c-assignedTo"> <?php echo $this->design->printAssignedHtml($design, $users);?></td>
<td class='c-actions text-center'>
<?php
$vars = "design={$design->id}";
common::printIcon('design', 'edit', $vars, $design, 'list', 'alter', '', '', '', '', '', $design->project);
common::printIcon('design', 'viewCommit', $vars, $design, 'list', 'list-alt', '', 'iframe showinonlybody', true);
common::printIcon('design', 'delete', $vars, $design, 'list', 'trash', 'hiddenwin', '', '', '', '', $design->project);
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer table-statistic'>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php endif;?>
</div>
<?php include '../../common/view/footer.html.php';?>
+60
View File
@@ -0,0 +1,60 @@
<?php
/**
* The create view of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: create.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::set('type', $type);?>
<div id="mainContent" class="main-content fade">
<div class="center-block">
<div class="main-header">
<h2><?php echo $lang->design->create;?></h2>
</div>
<form class="load-indicator main-form form-ajax" method='post' enctype='multipart/form-data' id='dataform'>
<table class="table table-form">
<tbody>
<tr>
<th class='w-120px'><?php echo $lang->design->product;?></th>
<td><?php echo html::select('product', $products, $productID, "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th class='w-120px'><?php echo $lang->design->story;?></th>
<td><?php echo html::select('story', empty($stories) ? '' : $stories, '', "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->design->type;?></th>
<td><?php echo html::select('type', $lang->design->typeList, '', "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->design->name;?></th>
<td><?php echo html::input('name', '', "class='form-control'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->design->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', '', "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->design->file;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform', 'fileCount=1&percent=0.85');?></td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'><?php echo html::submitButton() . html::backButton();?></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+98
View File
@@ -0,0 +1,98 @@
<?php
/**
* The edit view of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: edit.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::set('type', $design->type);?>
<div id="mainContent" class="main-content fade">
<div class="center-block">
<div class="main-header">
<h2><?php echo $lang->design->edit;?></h2>
</div>
<form class="load-indicator main-form form-ajax" method='post' enctype='multipart/form-data' id='dataform'>
<table class="table table-form">
<tbody>
<tr>
<th class='w-120px'><?php echo $lang->design->product;?></th>
<td><?php echo html::select('product', $products, $design->product, "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th class='w-120px'><?php echo $lang->design->story;?></th>
<td><?php echo html::select('story', empty($stories) ? '' : $stories, $design->story, "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->design->type;?></th>
<td><?php echo html::select('type', $lang->design->typeList, $design->type, "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->design->name;?></th>
<td><?php echo html::input('name', $design->name, "class='form-control'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->design->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', $design->desc, 'class="form-control"');?></td>
</tr>
<tr>
<th><?php echo $lang->design->file;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform', 'fileCount=1&percent=0.85');?></td>
</tr>
<tr>
<th><?php echo $lang->story->checkAffection;?></th>
<td colspan='2'>
<div class='tabs'>
<ul class='nav nav-tabs'>
<li class='active'><a data-toggle='tab' href='#affectedTasks'><?php echo $lang->design->affectedTasks;?><span class='label label-danger label-badge label-circle'><?php echo count($design->tasks);?></span></a></li>
</ul>
<div class='tab-content'>
<div class='tab-pane active' id='affectedTasks'>
<table class='table'>
<thead>
<tr class='text-center'>
<th class='c-id'> <?php echo $lang->task->id;?></th>
<th class='c-name'> <?php echo $lang->task->name;?></th>
<th class='w-100px'> <?php echo $lang->task->assignedTo;?></th>
<th class='c-status'><?php echo $lang->task->status;?></th>
<th class='w-100px'> <?php echo $lang->task->consumed;?></th>
<th class='w-90px'> <?php echo $lang->task->left;?></th>
</tr>
</thead>
<tbody>
<?php foreach($design->tasks as $task):?>
<tr class='text-center'>
<td><?php $task->id?></td>
<td class='text-left'><?php echo html::a($this->createLink('task', 'view', "taskID=$task->id"), $task->name, '_blank');?></td>;
<td><?php echo zget($users, $task->assignedTo);?></td>
<td><span class='status-task status-<?php echo $task->status;?>'><?php $this->processStatus('task', $task);?></span></td>
<td><?php echo $task->consumed;?></td>
<td><?php echo $task->left;?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'><?php echo html::submitButton() . html::backButton();?></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+88
View File
@@ -0,0 +1,88 @@
<?php
/**
* The linkCommit view of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: linkcommit.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='main-content' id='mainContent'>
<div class='main-header'>
<h2>
<span class='label label-id'><?php echo $design->id;?></span>
<span title='<?php echo $design->name?>'><?php echo $design->name?></span>
<small><?php echo $lang->arrow . $lang->design->linkCommit;?></small>
</h2>
</div>
<?php if(empty($repoID)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->design->noCommit;?></span></p>
</div>
<?php else:?>
<div class='searchBox'>
<table class="table">
<tr>
<td class="w-100px"><h4><?php echo $lang->repo->maintain . ': ';?></h4></td>
<td><?php echo html::select('repo', $repos, $repoID, "class='form-control chosen'");?></td>
<td>
<h4><?php echo $lang->design->commitDate . ':';?></h4>
<?php echo html::input('begin', $begin, "class='form-control form-date srearch-date'");?>
<span>~</span>
<?php echo html::input('end', $end, "class='form-control form-date srearch-date'");?>
</td>
</tr>
</table>
</div>
<form id='logForm' class='main-table form-ajax' data-ride='table' action=<?php echo inlink('linkCommit', "designID=$designID&repoID=$repoID");?> method='post'>
<table class='table'>
<thead>
<tr>
<th class='w-40px'></th>
<th class='w-100px'><?php echo $lang->repo->revisionA?></th>
<?php if(isset($repo->SCM) and $repo->SCM == 'Git'):?>
<th class='w-70px'><?php echo $lang->repo->commit?></th>
<?php endif;?>
<th class='w-120px'><?php echo $lang->repo->time?></th>
<th class='w-100px'><?php echo $lang->repo->committer?></th>
<th><?php echo $lang->repo->comment?></th>
</tr>
</thead>
<tbody>
<?php foreach($revisions as $log):?>
<tr>
<td class='c-name'>
<div class='checkbox-primary'>
<input type='checkbox' name='revision[]' value="<?php echo $log->id?>"/>
<label></label>
</div>
</td>
<td class='versions c-name' title="<?php echo $repo->SCM == 'Git' ? substr($log->revision, 0, 10) : $log->revision;?>"><span class="revision"><?php echo html::a($this->repo->createLink('revision', "repoID=$repoID&revision={$log->revision}"), $repo->SCM == 'Git' ? substr($log->revision, 0, 10) : $log->revision);?></span></td>
<?php if($repo->SCM == 'Git'):?>
<td><?php echo $log->commit?></td>
<?php endif;?>
<td><?php echo substr($log->time, 0, 10);?></td>
<td><?php echo zget($users, $log->committer, $log->committer);?></td>
<?php $comment = htmlspecialchars($log->comment, ENT_QUOTES);?>
<td title='<?php echo $comment?>' class='comment c-name'><?php echo $log->comment?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php echo html::submitButton('', '', 'btn btn-primary')?>
</div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php endif;?>
</div>
<?php js::set('designID', $designID);?>
<?php js::set('errorDate', $lang->design->errorDate);?>
<?php include '../../common/view/footer.html.php';?>
+92
View File
@@ -0,0 +1,92 @@
<?php
/**
* The view of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: view.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('type', $design->type);?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php $browseLink = $app->session->designList != false ? $app->session->designList : $this->createLink('design', 'browse', "productID=$design->product");?>
<?php if(!isonlybody()) echo html::a($browseLink, '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary'");?>
<div class="divider"></div>
<div class="page-title">
<span class="label label-id"><?php echo $design->id?></span>
<span class="text" title="<?php echo $design->name;?>"><?php echo $design->name;?></span>
<?php if($design->deleted):?>
<span class='label label-danger'><?php echo $lang->design->deleted;?></span>
<?php endif; ?>
</div>
</div>
</div>
<div id="mainContent" class="main-row">
<div class="main-col col-8">
<div class="cell">
<div class="detail">
<div class="detail-title"><?php echo $lang->design->desc;?></div>
<div class="detail-content article-content">
<?php echo $design->desc;?>
</div>
</div>
<?php echo $this->fetch('file', 'printFiles', array('files' => $design->files, 'fieldset' => 'true'));?>
</div>
<div class='cell'><?php include '../../common/view/action.html.php';?></div>
<div class='main-actions'>
<div class="btn-toolbar">
<?php common::printBack($this->session->designList);?>
<?php if(!isonlybody()) echo "<div class='divider'></div>";?>
<?php if(!$design->deleted):?>
<?php
common::printIcon('design', 'assignTo', "designID=$design->id", $design, 'button', '', '', 'iframe showinonlybody', true);
common::printIcon('design', 'linkCommit', "designID=$design->id", $design, 'button', 'link', '', 'iframe showinonlybody', true);
common::printIcon('design', 'edit', "designID=$design->id", $design, 'button', 'alter');
common::printIcon('design', 'delete', "designID=$design->id", $design, 'button', 'trash', 'hiddenwin');
?>
<?php endif;?>
</div>
</div>
</div>
<div class='side-col col-4'>
<div class='cell'>
<div class="detail">
<div class='detail-title'><?php echo $lang->design->basicInfo;?></div>
<div class='detail-content'>
<table class='table table-data'>
<tr>
<th><?php echo $lang->design->type;?></th>
<td><?php echo zget($lang->design->typeList, $design->type);?></td>
</tr>
<tr>
<th><?php echo $lang->design->product;?></th>
<td><?php echo $design->productName;?></td>
</tr>
<tr>
<th><?php echo $lang->design->story;?></th>
<td><?php echo $design->story ? html::a($this->createLink('story', 'view', "id=$design->story"), zget($stories, $design->story)) : '';?></td>
</tr>
<tr>
<th><?php echo $lang->design->submission;?></th>
<td><?php echo $design->commit;?></td>
</tr>
<tr>
<th><?php echo $lang->design->createdBy;?></th>
<td><?php echo zget($users, $design->createdBy);?></td>
</tr>
<tr>
<th><?php echo $lang->design->createdDate;?></th>
<td><?php echo substr($design->createdDate, 0, 11);?></td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+63
View File
@@ -0,0 +1,63 @@
<?php
/**
* The viewCommit view of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: viewcommit.html.php 4903 2020-09-02 09:32:59Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<style>
#mainContent .pull-right{margin-bottom: 10px}
.table{border: 1px solid #ddd;}
</style>
<div id="mainContent">
<div class='main-header'>
<h2>
<span class='label label-id'><?php echo $design->id;?></span>
<span title='<?php echo $design->name?>'><?php echo $design->name?></span>
<small><?php echo $lang->arrow . $lang->design->submission;?></small>
</h2>
</div>
<div class='btn-toolbar pull-right'>
<?php common::printLink('design', 'linkCommit', "designID=$design->id", "<i class='icon icon-plus'></i>" . $lang->design->linkCommit, '_blank', "class='btn btn-primary'");?>
</div>
<?php if(empty($design->commit)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->design->noCommit;?></span></p>
</div>
<?php else:?>
<table class='table'>
<thead>
<tr>
<th class="w-100px"><?php echo $lang->design->submission;?></th>
<th class='w-120px'><?php echo $lang->design->commitBy;?></th>
<th class='w-100px'><?php echo $lang->design->commitDate;?></th>
<th><?php echo $lang->design->comment;?></th>
<th class="text-center w-50px"> <?php echo $lang->design->actions;?></th>
</tr>
</thead>
<tbody>
<?php foreach($design->commit as $commit):?>
<tr>
<td title="<?php echo $commit->id;?>"><?php echo html::a(helper::createLink('design', 'revision', "repoID=$commit->id"), "#$commit->id", '_blank');?></td>
<td><?php echo zget($users, $commit->committer, $commit->committer);?></td>
<td><?php echo substr($commit->time, 0, 11);?></td>
<td title="<?php echo $commit->comment;?>"><?php echo $commit->comment;?></td>
<td class="c-actions text-center">
<?php common::printIcon('design', 'unlinkCommit', "designID=$design->id&commitID=$commit->id", $design, 'list', 'unlink', 'hiddenwin', 'iframe showinonlybody', true);?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer table-statistic'>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</div>
<?php include '../../common/view/footer.html.php';?>
+3
View File
@@ -96,3 +96,6 @@ ol, ul {margin-bottom: 0}
.c-product, .c-execution, .c-lib {width: 80px !important;}
.header-btn .btn > .text {text-overflow: unset !important;}
.tree li.active > .tree-group a {font-weight: 700; color: #0c64eb;}
.tree li>.list-toggle {left: -4px; top: 0;}
+7 -1
View File
@@ -2,7 +2,7 @@
.addbtn {padding-top: 22px; height: 63px; border: 1px dashed #ddd; width: 60px;}
.addbtn .icon-plus {font-size: 18px; display: block; opacity: 0.5; transition: opacity .2s; text-shadow: 1px 1px 3px rgba(0,0,0,.2);}
.addbtn:hover .icon-plus {opacity: .9; animation: flash-icon 1s linear alternate infinite;}
#subHeader #dropMenu {min-width: 250px; box-sizing: inhert; max-height: inherit;}
#subHeader #dropMenu {min-width: 250px; box-sizing: inherit; max-height: inherit;}
#subHeader #dropMenu .table-col .list-group {padding-top: 10px;}
.main-col .block-files .panel-heading {padding-right: 20px;}
.main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;}
@@ -41,3 +41,9 @@
.title {font-size: 20px !important;}
.article-content.comment {width: 100% !important;}
.tree-group {position: relative;}
.tree-group > .module-name {white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; display: block;}
.tree-group .tree-actions {display: none; position: absolute; right: 0; top: 0; background-color: #fff; white-space: nowrap;}
.tree-group:hover > .module-name {width: calc(100% - 20px);}
.tree-group:hover .tree-actions {display: block}
+1 -1
View File
@@ -133,7 +133,7 @@ $(function()
$('#content').on('click', '.outline .outline-toggle i.icon-angle-right', function()
{
$('.article-content').css('width', '85%');
$('.article-content').width('85%');
$('.outline').css({'min-width' : '180px', 'border-left' : '2px solid #efefef'});
$(this).removeClass('icon-angle-right').addClass('icon-angle-left').css('left', '-9px');
$('.outline-content').show();
+8 -8
View File
@@ -29,12 +29,12 @@ $lang->doc->files = 'Files';
$lang->doc->addedBy = 'Author';
$lang->doc->addedDate = 'Added';
$lang->doc->editedBy = 'UpdatedBy';
$lang->doc->editedDate = 'UpdatedDate';
$lang->doc->editedDate = 'Updated';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Basic Info';
$lang->doc->basicInfo = 'Basic Information';
$lang->doc->deleted = 'Deleted';
$lang->doc->fileObject = 'Dependent Item';
$lang->doc->whiteList = 'White List';
$lang->doc->whiteList = 'Whitelist';
$lang->doc->contentType = 'Format';
$lang->doc->separator = "<i class='icon-angle-right'></i>";
$lang->doc->fileTitle = 'File Name';
@@ -51,7 +51,7 @@ $lang->doc->item = ' Items';
$lang->doc->num = 'Documents';
$lang->doc->searchResult = 'Search Result';
$lang->doc->mailto = 'Mailto';
$lang->doc->noModule = 'No document in this lib, please create it';
$lang->doc->noModule = 'No document in this library. Create one.';
$lang->doc->noChapter = 'No chapters or articles in this book. Please add chapters and articles.';
$lang->doc->views = 'Views';
$lang->doc->draft = 'Draft';
@@ -73,7 +73,7 @@ $lang->doc->todayEdited = 'Updated Today';
$lang->doc->pastEdited = 'Total Updated';
$lang->doc->myDoc = 'My Documents';
$lang->doc->myCollection = 'My Favorites';
$lang->doc->tableContents = 'Catalog';
$lang->doc->tableContents = 'Directory';
/* Methods list */
$lang->doc->index = 'Document Home';
@@ -91,12 +91,12 @@ $lang->doc->manageType = 'Manage Category';
$lang->doc->editType = 'Edit';
$lang->doc->deleteType = 'Delete';
$lang->doc->addType = 'Add';
$lang->doc->childType = 'Catalog';
$lang->doc->catalogName = 'Catalog Name';
$lang->doc->childType = 'Directory';
$lang->doc->catalogName = 'Name';
$lang->doc->collect = 'Add Favorite';
$lang->doc->cancelCollection = 'Remove Favorite';
$lang->doc->deleteFile = 'Delete File';
$lang->doc->menuTitle = 'Menu';
$lang->doc->menuTitle = 'Direcotory';
$lang->doc->collectAction = 'Add Favorite';
+51 -9
View File
@@ -737,7 +737,7 @@ class docModel extends model
}
unset($doc->contentType);
$doc->draft = $doc->content;
$doc->draft = isset($doc->content) ? $doc->content : '';
$this->dao->update(TABLE_DOC)->data($doc, 'content')
->autoCheck()
->batchCheck($requiredFields, 'notempty')
@@ -2274,7 +2274,7 @@ EOT;
if($startModule) $startModulePath = $startModule->path . '%';
}
$docs = $this->dao->select('*')->from(TABLE_DOC)
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('lib')->eq($rootID)
->andWhere('deleted')->eq(0)
->fetchAll();
@@ -2308,14 +2308,26 @@ EOT;
{
if(!$docID and $currentMethod != 'tablecontents') $docID = $doc->id;
$treeMenu[0] .= '<li' . ($doc->id == $docID ? ' class="active"' : ' class="independent"') . '>';
$treeMenu[0] .= '<li' . ($doc->id == $docID ? ' class="active"' : ' class="independent"') . " data-id=$doc->id>";
if($currentMethod == 'tablecontents')
{
$treeMenu[0] .= '<span class="tail-info">' . zget($users, $doc->editedBy) . ' &nbsp;' . $doc->editedDate . '</span>';
}
$treeMenu[0] .= html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$rootID&docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title' title='{$doc->title}'");
if($currentMethod == 'objectlibs')
{
$treeMenu[0] .= "<div class='tree-group'><span class='module-name'>" . html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$rootID&docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title' title='{$doc->title}'") . '</span>';
if(common::hasPriv('doc', 'edit'))
{
$treeMenu[0] .= "<div class='tree-actions'>";
$treeMenu[0] .= html::a(helper::createLink('doc', 'edit', "docID={$doc->id}&comment=false&objectType=$type&objectID=$objectID&libID=$rootID"), "<i class='icon icon-edit'></i>", '', "title={$this->lang->doc->edit}");
$treeMenu[0] .= '</div></div>';
}
}
else
{
$treeMenu[0] .= html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$rootID&docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title' title='{$doc->title}'");
}
$treeMenu[0] .= '</li>';
}
@@ -2362,13 +2374,28 @@ EOT;
else
{
if(!$docID and $currentMethod != 'tablecontents') $docID = $doc->id;
$treeMenu[$module->id] .= '<li' . ($doc->id == $docID ? ' class="active"' : ' class="doc"') . '>';
$treeMenu[$module->id] .= '<li' . ($doc->id == $docID ? ' class="active"' : ' class="doc"') . " data-id=$doc->id>";
if($currentMethod == 'tablecontents')
{
$treeMenu[$module->id] .= '<span class="tail-info">' . zget($users, $doc->editedBy) . ' &nbsp;' . $doc->editedDate . '</span>';
}
$treeMenu[$module->id] .= html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$libID&docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title' title='{$doc->title}'");
if($currentMethod == 'objectlibs')
{
$treeMenu[$module->id] .= "<div class='tree-group'><span class='module-name'>" . html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$libID&docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title' title='{$doc->title}'") . '</span>';
if(common::hasPriv('doc', 'edit'))
{
$treeMenu[$module->id] .= "<div class='tree-actions'>";
$treeMenu[$module->id] .= html::a(helper::createLink('doc', 'edit', "docID=$docID&comment=false&objectType=$type&objectID=$objectID&libID=$libID"), "<i class='icon icon-edit'></i>", '', "title={$this->lang->doc->edit}");
$treeMenu[$module->id] .= '</div>';
}
$treeMenu[$module->id] .= '</div>';
}
elseif($currentMethod == 'tablecontents')
{
$treeMenu[$module->id] .= html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$libID&docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title' title='{$doc->title}'");
}
$treeMenu[$module->id] .= '</li>';
}
@@ -2381,7 +2408,22 @@ EOT;
}
else
{
$li = "<a title='{$module->name}'>" . $module->name . '</a>';
if($currentMethod == 'tablecontents')
{
$li = "<a title='{$module->name}'>" . $module->name . '</a>';
}
else
{
$li = "<div class='tree-group'><span class='module-name'><a class='sort-module' title='{$module->name}'>" . $module->name . '</a></span>';
if(common::hasPriv('tree', 'edit') or common::hasPriv('tree', 'browse'))
{
$li .= "<div class='tree-actions'>";
if(common::hasPriv('tree', 'edit')) $li .= html::a(helper::createLink('tree', 'edit', "module=$module->id&type=doc"), "<i class='icon icon-edit'></i>", '', "data-toggle='modal' title={$this->lang->doc->editType}");
if(common::hasPriv('tree', 'browse')) $li .= html::a(helper::createLink('tree', 'browse', "rootID=$libID&type=doc&module=$module->id", '', 1), "<i class='icon icon-split'></i>", '', "class='iframe' title={$this->lang->doc->editType}");
$li .= '</div>';
}
$li .= '</div>';
}
}
if($treeMenu[$module->id])
{
@@ -2410,7 +2452,7 @@ EOT;
}
}
$treeMenu[$module->parent] .= '<li class="' . implode(' ', $class) . '">' . $li . '</li>';
$treeMenu[$module->parent] .= '<li class=" can-sort ' . implode(' ', $class) . '" data-id=' . $module->id . '>' . $li . '</li>';
}
/**
+100 -140
View File
@@ -15,149 +15,109 @@ if(empty($type)) $type = 'product';
$sideWidth = common::checkNotCN() ? '270' : '238';
?>
<div class="side-col" style="width:<?php echo $sideWidth;?>px" data-min-width="<?php echo $sideWidth;?>">
<div class="cell" id="<?php echo $type;?>">
<div id='title'>
<li class='menu-title'><?php echo $this->lang->doc->menuTitle;?></li>
<?php
$canEditLib = common::hasPriv('doc', 'editLib');
$canManageBook = common::hasPriv('doc', 'manageBook');
$canManageMenu = common::hasPriv('tree', 'browse');
$canEditLib = common::hasPriv('doc', 'editLib');
$canDeleteLib = common::hasPriv('doc', 'deleteLib');
if($type != 'book' and ($canManageMenu or $canEditLib or $canDeleteLib))
{
echo "<div class='menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canManageMenu)
{
echo '<li>' . html::a($this->createLink('tree', 'browse', "rootID=$libID&view=doc", '', true), '<i class="icon-cog-outline"></i> ' . $this->lang->doc->manageType, '', "class='iframe'") . '</li>';
echo "<li class='divider'></li>";
}
if($canEditLib) echo '<li>' . html::a($this->createLink('doc', 'editLib', "rootID=$libID"), '<i class="icon-edit"></i> ' . $lang->doc->editLib, '', "class='iframe'") . '</li>';
if($canDeleteLib) echo '<li>' . html::a($this->createLink('doc', 'deleteLib', "rootID=$libID"), '<i class="icon-trash"></i> ' . $lang->doc->deleteLib, 'hiddenwin') . '</li>';
echo '</ul></div>';
}
<div class="cell" id="<?php echo $type;?>">
<div id='title'>
<li class='menu-title'><?php echo $this->lang->doc->menuTitle;?></li>
<?php
$canEditLib = common::hasPriv('doc', 'editLib');
$canManageBook = common::hasPriv('doc', 'manageBook');
$canManageMenu = common::hasPriv('tree', 'browse');
$canEditLib = common::hasPriv('doc', 'editLib');
$canDeleteLib = common::hasPriv('doc', 'deleteLib');
if($type != 'book' and ($canManageMenu or $canEditLib or $canDeleteLib))
{
echo "<div class='menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canManageMenu)
{
echo '<li>' . html::a($this->createLink('tree', 'browse', "rootID=$libID&view=doc", '', true), '<i class="icon-cog-outline"></i> ' . $this->lang->doc->manageType, '', "class='iframe'") . '</li>';
echo "<li class='divider'></li>";
}
if($canEditLib) echo '<li>' . html::a($this->createLink('doc', 'editLib', "rootID=$libID"), '<i class="icon-edit"></i> ' . $lang->doc->editLib, '', "class='iframe'") . '</li>';
if($canDeleteLib) echo '<li>' . html::a($this->createLink('doc', 'deleteLib', "rootID=$libID"), '<i class="icon-trash"></i> ' . $lang->doc->deleteLib, 'hiddenwin') . '</li>';
echo '</ul></div>';
}
if($type == 'book' and ($canEditLib or $canManageBook))
{
echo "<div class='menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canEditLib) echo '<li>' . html::a($this->createLink('doc', 'editLib', "rootID=$libID"), '<i class="icon-edit"></i> ' . $lang->doc->editBook, '', "class='iframe'") . '</li>';
if($canManageBook) echo '<li>' . html::a($this->createLink('doc', 'manageBook', "bookID=$libID"), '<i class="icon-cog-outline"></i> ' . $lang->doc->manageBook) . '</li>';
echo '</ul></div>';
}
?>
</div>
<?php if(!$moduleTree):?>
<hr class="space">
<div class="text-center text-muted tips">
<?php echo $type == 'book' ? $lang->doc->noChapter : $lang->doc->noModule;?>
</div>
<hr class="space">
<?php endif;?>
<?php if($type == 'book'):?>
<?php include './bookside.html.php';?>
<?php else:?>
<?php echo $moduleTree;?>
<?php endif;?>
if($type == 'book' and ($canEditLib or $canManageBook))
{
echo "<div class='menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canEditLib) echo '<li>' . html::a($this->createLink('doc', 'editLib', "rootID=$libID"), '<i class="icon-edit"></i> ' . $lang->doc->editBook, '', "class='iframe'") . '</li>';
if($canManageBook) echo '<li>' . html::a($this->createLink('doc', 'manageBook', "bookID=$libID"), '<i class="icon-cog-outline"></i> ' . $lang->doc->manageBook) . '</li>';
echo '</ul></div>';
}
?>
</div>
<script>
$(function()
{
if($.cookie('docSideType'))
{
var type = $.cookie('docSideType');
var $tabs = $('#mainRow .side-col .tabs');
if($tabs.find('.tab-content .tab-pane#' + type).length >0)
{
$tabs.find('.nav-tabs li').removeClass('active');
$tabs.find('.nav-tabs li a[href="#' + type + '"]').parent().addClass('active');
$tabs.find('.tab-content .tab-pane').removeClass('active');
$tabs.find('.tab-content .tab-pane#' + type).addClass('active');
}
$.cookie('docSideType', '');
$('#mainRow .side-col .side-footer #orderLib').toggleClass('hidden', (type == 'product' || type == 'execution'));
}
<?php if(!$moduleTree):?>
<hr class="space">
<div class="text-center text-muted tips">
<?php echo $type == 'book' ? $lang->doc->noChapter : $lang->doc->noModule;?>
</div>
<hr class="space">
<?php endif;?>
<?php if($type == 'book'):?>
<?php include './bookside.html.php';?>
<?php else:?>
<?php echo $moduleTree;?>
<?php endif;?>
</div>
<style>
.sortable-sorting .module-name > a {cursor: move;}
.sortable-sorting li >.tree-group {opacity: .5;}
.sortable-sorting .drop-here .tree-group {background-color: #fff3e0;}
.sortable-sorting .drop-here .tree-group > * {opacity: .1;}
.sortable-sorting .drag-shadow .tree-group {opacity: 1!important;}
.sortable-sorting .drag-shadow .tree-actions {visibility: hidden;}
.is-sorting > li > .tree-group {opacity: 1; border-radius: 4px;}
.is-sorting > li ul {display: none!important;}
</style>
<script>
$(function()
{
/* Make modules tree sortable */
$('#modules').sortable(
{
trigger: '.module-name>a.sort-module',
dropToClass: 'sort-to',
stopPropagation: true,
nested: true,
selector: 'li',
dragCssClass: 'drop-here',
targetSelector: function($ele, $root)
{
var $ul = $ele.closest('ul');
setTimeout(function()
{
if($('#modules').hasClass('sortable-sorting')) $ul.addClass('is-sorting');
}, 100);
return $ul.children('li');
},
always: function()
{
$('#modules,#modules .is-sorting').removeClass('is-sorting');
},
finish: function(e)
{
if(!e.changed) return;
$('#mainRow .side-col .tabs .nav-tabs li a').click(function()
{
var href = $(this).attr('href');
var canOrder = !(href.indexOf('product') > 0 || href.indexOf('execution') > 0);
if(!canOrder)
{
$(this).closest('.side-col').find('.side-footer #orderLib').addClass('hidden');
$(this).closest('.side-col').find('.side-footer #saveOrder').addClass('hidden');
}
var orders = {};
$('#modules').find('li.can-sort').each(function()
{
var $li = $(this);
var $orderLib = $(this).closest('.side-col').find('.side-footer #orderLib');
var $saveOrder = $(this).closest('.side-col').find('.side-footer #saveOrder');
var item = $li.data();
'<?php echo $type;?>' == 'book' ? orders['sort[' + item.id + ']'] = $li.attr('data-order') || item.order : orders['orders[' + item.id + ']'] = $li.attr('data-order') || item.order;
});
var execute = false;
$(this).on('shown.zui.tab', function()
{
if(!execute)
{
var $tabPane = $('#mainRow .side-col .tabs .tab-content .tab-pane.active');
if($tabPane.find('.libs-group.sort').length > 0 && canOrder)
{
$orderLib.addClass('hidden');
$saveOrder.removeClass('hidden');
execute = true;
}
if($tabPane.find('.libs-group.sort').length == 0 && canOrder)
{
$orderLib.removeClass('hidden');
$saveOrder.addClass('hidden');
execute = true;
}
}
});
});
$('#orderLib').click(function()
{
var $tabPane = $('#mainRow .side-col .tabs .tab-content .tab-pane.active');
var type = $tabPane.attr('id');
$.get(createLink('doc', 'sort', "type=" + type), function(data)
{
$tabPane.html(data);
$tabPane.closest('.side-col').find('.side-footer #orderBox #orderLib').addClass('hidden');
$tabPane.closest('.side-col').find('.side-footer #orderBox #saveOrder').removeClass('hidden');
$tabPane.find('.libs-group.sort').sortable(
{
trigger: '.lib',
selector: '.lib',
});
});
});
});
function saveOrder()
{
var $tabPane = $('#mainRow .side-col .tabs .tab-content .tab-pane.active');
var type = $tabPane.attr('id');
var orders = {};
var orderNext = 1;
$tabPane.find('.libs-group.sort .lib').not('.files').not('.addbtn').each(function()
{
orders[$(this).data('id')] = orderNext ++;
});
$.post(createLink('doc', 'sort'), orders, function(data)
{
if(data.result == 'success')
{
$.cookie('docSideType', type);
return location.reload();
}
else
{
bootbox.alert(data.message);
}
}, 'json');
}
</script>
var link = '<?php echo $type;?>' == 'book' ? createLink('doc', 'sortBookOrder') : createLink('tree', 'updateOrder');
$.post(link, orders, function(data){}).error(function()
{
bootbox.alert(lang.timeout);
});
}
});
});
</script>
</div>
+188 -35
View File
@@ -40,6 +40,7 @@ class execution extends control
$this->loadModel('project');
if(defined('IN_UPGRADE') and IN_UPGRADE) return false;
$this->executions = $this->execution->getPairs(0, 'all', 'nocode');
$skipCreateStep = array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers');
if(!in_array($this->methodName, $skipCreateStep) and $this->app->tab == 'execution')
@@ -137,6 +138,7 @@ class execution extends control
$this->loadModel('task');
$this->loadModel('datatable');
$this->loadModel('setting');
$this->loadModel('product');
if(common::hasPriv('execution', 'create')) $this->lang->TRActions = html::a($this->createLink('execution', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->execution->create, '', "class='btn btn-primary'");
@@ -148,7 +150,7 @@ class execution extends control
/* Get products by execution. */
$execution = $this->commonAction($executionID, $status);
$executionID = $execution->id;
$products = $this->loadModel('product')->getProductPairsByProject($executionID);
$products = $this->product->getProductPairsByProject($executionID);
setcookie('preExecutionID', $executionID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
/* Save the recently five executions visited in the cookie. */
@@ -216,6 +218,19 @@ class execution extends control
$tasks = $this->execution->getTasks($productID, $executionID, $this->executions, $browseType, $queryID, $moduleID, $sort, $pager);
}
/* Get product. */
if(empty($productID))
{
$productModule = $this->tree->getById($moduleID);
if(!empty($productModule) and $productModule->type != 'task') $product = $this->product->getById($productModule->root);
}
if(empty($product)) $product = $this->product->getById($productID);
if(!empty($product) and $product->type != 'normal')
{
$this->lang->datatable->showBranch = sprintf($this->lang->datatable->showBranch, $this->lang->product->branchName[$product->type]);
}
/* Build the search form. */
$actionURL = $this->createLink('execution', 'task', "executionID=$executionID&status=bySearch&param=myQueryID");
$this->config->execution->search['onMenuBar'] = 'yes';
@@ -245,6 +260,7 @@ class execution extends control
$this->view->executionID = $executionID;
$this->view->execution = $execution;
$this->view->productID = $productID;
$this->view->product = $product;
$this->view->modules = $this->tree->getTaskOptionMenu($executionID, 0, 0, $showAllModule ? 'allModule' : '');
$this->view->moduleID = $moduleID;
$this->view->moduleTree = $this->tree->getTaskTreeMenu($executionID, $productID, $startModuleID = 0, array('treeModel', 'createTaskLink'), $extra);
@@ -671,6 +687,7 @@ class execution extends control
$this->loadModel('story');
$this->loadModel('user');
$this->loadModel('datatable');
$this->app->loadLang('datatable');
$this->app->loadLang('testcase');
$type = strtolower($type);
@@ -778,8 +795,22 @@ class execution extends control
foreach($plans as $plan) $allPlans += $plan;
}
if($this->cookie->storyModuleParam) $this->view->module = $this->loadModel('tree')->getById($this->cookie->storyModuleParam);
if($this->cookie->storyProductParam) $this->view->product = $this->loadModel('product')->getById($this->cookie->storyProductParam);
if($this->cookie->storyModuleParam)
{
$module = $this->loadModel('tree')->getById($this->cookie->storyModuleParam);
$this->view->module = $module;
$product = $this->product->getById($module->root);
$this->lang->datatable->showBranch = sprintf($this->lang->datatable->showBranch, $this->lang->product->branchName[$product->type]);
}
if($this->cookie->storyProductParam)
{
$product = $this->loadModel('product')->getById($this->cookie->storyProductParam);
$this->view->product = $product;
$this->lang->datatable->showBranch = sprintf($this->lang->datatable->showBranch, $this->lang->product->branchName[$product->type]);
}
if($this->cookie->storyBranchParam)
{
$branchID = $this->cookie->storyBranchParam;
@@ -1236,6 +1267,8 @@ class execution extends control
unset($this->lang->doc->menu->execution['subMenu']);
}
$project = $this->project->getByID($projectID);
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
parse_str($extra, $output);
@@ -1486,7 +1519,8 @@ class execution extends control
$executions = array('' => '') + $this->executions;
$execution = $this->execution->getById($executionID);
$managers = $this->execution->getDefaultManagers($executionID);
$managers = $this->execution->getDefaultManagers($executionID);
/* Remove current execution from the executions. */
unset($executions[$executionID]);
@@ -1896,50 +1930,81 @@ class execution extends control
* Kanban.
*
* @param int $executionID
* @param string $type
* @param string $browseType story|bug|task|all
* @param string $orderBy
* @param string $groupBy
* @access public
* @return void
*/
public function kanban($executionID, $type = 'story', $orderBy = 'order_asc')
public function kanban($executionID, $browseType = '', $orderBy = 'order_asc', $groupBy = '')
{
if(empty($browseType)) $browseType = $this->session->kanbanType ? $this->session->kanbanType : 'all';
if(empty($groupBy) and $browseType != 'all') $groupBy = $this->session->{'kanbanGroupBy' . $browseType} ? $this->session->{'kanbanGroupBy' . $browseType} : 'default';
if(empty($groupBy) and $browseType == 'all') $groupBy = 'default';
/* Save to session. */
$uri = $this->app->getURI(true);
$this->app->session->set('taskList', $uri, 'execution');
$this->app->session->set('bugList', $uri, 'qa');
$this->app->session->set('taskList', $uri, 'execution');
$this->app->session->set('bugList', $uri, 'qa');
$this->app->session->set('kanbanType', $browseType, 'execution');
$this->app->session->set('kanbanGroupBy' . $browseType, $groupBy, 'execution');
/* Compatibility IE8*/
/* Load language. */
$this->app->loadLang('story');
$this->app->loadLang('task');
$this->app->loadLang('bug');
/* Compatibility IE8. */
if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7");
$kanbanGroup = $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy);
if(empty($kanbanGroup))
{
$this->kanban->createLanes($executionID, $browseType, $groupBy);
$kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy);
}
$this->execution->setMenu($executionID);
$execution = $this->loadModel('execution')->getById($executionID);
$tasks = $this->execution->getKanbanTasks($executionID, "id");
$bugs = $this->loadModel('bug')->getExecutionBugs($executionID);
$stories = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, $orderBy);
/* Determines whether an object is editable. */
$canBeChanged = common::canModify('execution', $execution);
$kanbanGroup = $this->execution->getKanbanGroupData($stories, $tasks, $bugs, $type);
$kanbanSetting = $this->execution->getKanbanSetting();
/* Get execution's product. */
$productID = 0;
$products = $this->loadModel('product')->getProducts($executionID);
if($products) $productID = key($products);
$plans = $this->execution->getPlans($products);
$allPlans = array('' => '');
if(!empty($plans))
{
foreach($plans as $plan) $allPlans += $plan;
}
$userList = array();
$avatarPairs = $this->dao->select('account, avatar')->from(TABLE_USER)->where('deleted')->eq(0)->fetchPairs();
foreach($avatarPairs as $account => $avatar)
{
if(!$avatar) continue;
$userList[$account]['avatar'] = $avatar;
}
$this->view->title = $this->lang->execution->kanban;
$this->view->position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
$this->view->position[] = $this->lang->execution->kanban;
$this->view->stories = $stories;
$this->view->realnames = $this->loadModel('user')->getPairs('noletter');
$this->view->storyOrder = $orderBy;
$this->view->orderBy = 'id_asc';
$this->view->executionID = $executionID;
$this->view->browseType = '';
$this->view->execution = $execution;
$this->view->type = $type;
$this->view->productID = $productID;
$this->view->allPlans = $allPlans;
$this->view->browseType = $browseType;
$this->view->kanbanGroup = $kanbanGroup;
$this->view->kanbanColumns = $this->execution->getKanbanColumns($kanbanSetting);
$this->view->statusMap = $canBeChanged ? $this->execution->getKanbanStatusMap($kanbanSetting) : array();
$this->view->statusList = $this->execution->getKanbanStatusList($kanbanSetting);
$this->view->colorList = $this->execution->getKanbanColorList($kanbanSetting);
$this->view->execution = $execution;
$this->view->groupBy = $groupBy;
$this->view->canBeChanged = $canBeChanged;
$this->view->userList = $userList;
$this->display();
}
@@ -1954,7 +2019,7 @@ class execution extends control
{
$this->loadModel('project');
$projects = $this->project->getPairsByProgram(0, 'noclosed');
$executions = $this->project->getStats(0, 'all');
$executions = $this->project->getStats(0, 'all', 0, 0, 30, 'id_desc');
$teams = $this->dao->select('root,account')->from(TABLE_TEAM)
->where('root')->in($this->app->user->view->sprints)
@@ -1982,18 +2047,38 @@ class execution extends control
$statusCount[$status] += isset($kanbanGroup[$projectID][$status]) ? count($kanbanGroup[$projectID][$status]) : 0;
/* Max 5 closed executions. */
/* Max 2 closed executions. */
if($status == 'closed')
{
if(isset($myExecutions[$status]) and count($myExecutions[$status]) >= 5) $myExecutions[$status] = array_slice($myExecutions[$status], 0, 5, true);
if(isset($kanbanGroup[$projectID][$status]) and count($kanbanGroup[$projectID][$status]) >= 5) $kanbanGroup[$projectID][$status] = array_slice($kanbanGroup[$projectID][$status], 0, 5, true);
if(isset($myExecutions[$status]) and count($myExecutions[$status]) > 2)
{
foreach($myExecutions[$status] as $executionID => $execution)
{
unset($myExecutions[$status][$executionID]);
$myExecutions[$status][$execution->closedDate] = $execution;
}
krsort($myExecutions[$status]);
$myExecutions[$status] = array_slice($myExecutions[$status], 0, 2, true);
}
if(isset($kanbanGroup[$projectID][$status]) and count($kanbanGroup[$projectID][$status]) > 2)
{
foreach($kanbanGroup[$projectID][$status] as $executionID => $execution)
{
unset($kanbanGroup[$projectID][$status][$executionID]);
$kanbanGroup[$projectID][$status][$execution->closedDate] = $execution;
}
krsort($kanbanGroup[$projectID][$status]);
$kanbanGroup[$projectID][$status] = array_slice($kanbanGroup[$projectID][$status], 0, 2);
}
}
}
if(empty($kanbanGroup[$projectID])) continue;
$projectCount++;
}
krsort($kanbanGroup);
$this->view->title = $this->lang->execution->executionKanban;
$this->view->kanbanGroup = empty($myExecutions) ? $kanbanGroup : array($myExecutions) + $kanbanGroup;
@@ -2119,6 +2204,14 @@ class execution extends control
}
}
/* Close the page when there is no data. */
$hasData = false;
foreach($datas as $data)
{
if(!empty($data)) $hasData = true;
}
if(!$hasData) die(js::alert($this->lang->execution->noPrintData) . js::close());
$this->execution->saveKanbanData($executionID, $originalDatas);
$hasBurn = $this->post->content == 'all';
@@ -2144,8 +2237,7 @@ class execution extends control
$this->execution->setMenu($executionID);
$execution = $this->execution->getById($executionID);
$this->view->position[] = html::a($this->createLink('execution', 'browse', "executionID=$executionID"), $execution->name);
$this->view->position[] = $this->lang->execution->printKanban;
$this->view->executionID = $executionID;
$this->display();
}
@@ -2471,6 +2563,8 @@ class execution extends control
{
$this->execution->linkStory($objectID);
if($object->type != 'project' and $object->project != 0) $this->execution->linkStory($object->project);
if(isonlybody()) die(js::reload('parent'));
die(js::locate($browseLink));
}
@@ -2946,7 +3040,7 @@ class execution extends control
* @access public
* @return void
*/
public function all($status = 'all', $projectID = 0, $orderBy = 'id_desc', $productID = 0, $recTotal = 0, $recPerPage = 10, $pageID = 1)
public function all($status = 'all', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $recTotal = 0, $recPerPage = 10, $pageID = 1)
{
$this->app->loadLang('my');
$this->app->loadLang('product');
@@ -3190,13 +3284,14 @@ class execution extends control
/**
* Import stories by plan.
*
* @param int $executionID
* @param int $planID
* @param int $productID
* @param int $executionID
* @param int $planID
* @param int $productID
* @param string $fromMethod
* @access public
* @return void
*/
public function importPlanStories($executionID, $planID, $productID = 0)
public function importPlanStories($executionID, $planID, $productID = 0, $fromMethod = 'story')
{
$planStories = $planProducts = array();
$planStory = $this->loadModel('story')->getPlanStories($planID);
@@ -3231,7 +3326,7 @@ class execution extends control
$param = "projectID=$executionID";
}
if($count != 0) echo js::alert(sprintf($this->lang->execution->haveDraft, $count)) . js::locate($this->createLink($moduleName, 'story', $param));
die(js::locate(helper::createLink($moduleName, 'story', $param), 'parent'));
die(js::locate(helper::createLink($moduleName, $fromMethod, $param)));
}
/**
@@ -3317,4 +3412,62 @@ class execution extends control
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
}
/**
*Ajax get group menu of lanes.
*
* @param string $type all|syory|task|bug
* @param string $group
* @access public
* @return void
*/
public function ajaxGetGroup($type, $group = 'default')
{
$this->app->loadLang('kanban');
$groups = array();
$groups = $this->lang->kanban->group->$type;
die(html::select("group", $groups, $group, 'class="form-control chosen" data-max_drop_width="215"'));
}
/**
* Ajax update kanban.
*
* @param int $executionID
* @param string $enterTime
* @param string $browseType
* @param string $groupBy
* @access public
* @return void
*/
public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '')
{
$enterTime = date('Y-m-d H:i:s', $enterTime);
$lastEditedTime = $this->dao->select("max(lastEditedTime) as lastEditedTime")->from(TABLE_KANBANLANE)->where('execution')->eq($executionID)->fetch('lastEditedTime');
if($lastEditedTime > $enterTime)
{
$kanbanGroup = $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy);
die(json_encode($kanbanGroup));
}
else
{
die('');
}
}
/**
* AJAX: Update the execution name.
*
* @param int $executionID
* @param string $newExecutionName
* @access public
* @return bool
*/
public function ajaxUpdateExecutionName($executionID, $newExecutionName)
{
$this->dao->update(TABLE_EXECUTION)->set('name')->eq($newExecutionName)->where('id')->eq($executionID)->exec();
if(dao::isError()) echo false;
echo true;
}
}

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