Merge branch 'master' into zenops_61

This commit is contained in:
zhaoke
2023-02-07 02:04:56 +00:00
145 changed files with 2135 additions and 1034 deletions
+1 -1
View File
@@ -417,7 +417,7 @@ $config->pipelineTypeList = array('gitlab', 'gogs', 'gitea', 'jenkins', 'sonarqu
$config->programPriv = new stdclass();
$config->programPriv->noSprint = array('task', 'story', 'tree', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'stakeholder', 'projectrelease', 'requirement');
$config->programPriv->scrum = array('story', 'requirement', 'productplan', 'tree', 'projectplan', 'projectstory', 'projectrelease', 'project', 'execution', 'build', 'bug', 'testcase', 'testreport', 'doc', 'repo', 'meeting', 'stakeholder', 'testtask');
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('task', 'workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->waterfallModules = array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'opportunity', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport');
+2 -2
View File
@@ -134,7 +134,7 @@ CREATE TABLE `zt_apistruct` (
`lib` int(10) unsigned NOT NULL DEFAULT '0',
`name` varchar(30) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` mediumtext NOT NULL DEFAULT '',
`desc` mediumtext NOT NULL,
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
`attribute` text,
`addedBy` varchar(30) NOT NULL DEFAULT '0',
@@ -1239,7 +1239,7 @@ CREATE TABLE `zt_im_chat` (
`lastMessageIndex` int(11) unsigned NOT NULL DEFAULT 0,
`dismissDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`pinnedMessages` text NOT NULL,
`mergedChats` text NOT NULL DEFAULT '',
`mergedChats` text NOT NULL,
`adminInvite` enum('0','1') NOT NULL DEFAULT '0',
`avatar` text NOT NULL DEFAULT '',
`archiveDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+2
View File
@@ -1,2 +1,4 @@
ALTER TABLE `zt_image` ADD `localName` VARCHAR(64) NOT NULL AFTER `name`;
ALTER TABLE `zt_image` ADD `restoreDate` datetime NOT NULL AFTER `createdDate`;
ALTER TABLE `zt_ticket` MODIFY `resolution` text NOT NULL;
+228 -274
View File
@@ -10,19 +10,20 @@ CREATE TABLE IF NOT EXISTS `zt_acl` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_action`;
CREATE TABLE IF NOT EXISTS `zt_action` (
`id` int(9) unsigned NOT NULL auto_increment,
`objectType` varchar(30) NOT NULL default '',
`objectID` mediumint(8) unsigned NOT NULL default '0',
`id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(30) NOT NULL DEFAULT '',
`objectID` mediumint(8) unsigned NOT NULL DEFAULT '0',
`product` text NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`execution` mediumint(8) unsigned NOT NULL,
`actor` varchar(100) NOT NULL default '',
`action` varchar(30) NOT NULL default '',
`actor` varchar(100) NOT NULL DEFAULT '',
`action` varchar(80) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`comment` text NOT NULL,
`extra` text NOT NULL,
`read` enum('0','1') NOT NULL default '0',
`extra` text,
`read` enum('0','1') NOT NULL DEFAULT '0',
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`efforted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `date` (`date`),
KEY `actor` (`actor`),
@@ -98,7 +99,7 @@ CREATE TABLE IF NOT EXISTS `zt_apistruct` (
`lib` int UNSIGNED NOT NULL DEFAULT 0,
`name` varchar(30) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`desc` mediumtext NOT NULL DEFAULT '',
`desc` mediumtext NOT NULL,
`version` smallint unsigned NOT NULL DEFAULT 0,
`attribute` text NULL,
`addedBy` varchar(30) NOT NULL DEFAULT 0,
@@ -245,53 +246,56 @@ CREATE TABLE IF NOT EXISTS `zt_branch` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_bug`;
CREATE TABLE IF NOT EXISTS `zt_bug` (
`id` mediumint(8) NOT NULL auto_increment,
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
`project` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`module` mediumint(8) unsigned NOT NULL default '0',
`execution` mediumint(8) unsigned NOT NULL default '0',
`plan` mediumint(8) unsigned NOT NULL default '0',
`story` mediumint(8) unsigned NOT NULL default '0',
`storyVersion` smallint(6) NOT NULL default '1',
`task` mediumint(8) unsigned NOT NULL default '0',
`toTask` mediumint(8) unsigned NOT NULL default '0',
`toStory` mediumint(8) NOT NULL default '0',
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`injection` mediumint(8) unsigned NOT NULL,
`identify` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`execution` mediumint(8) unsigned NOT NULL DEFAULT '0',
`plan` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`toTask` mediumint(8) unsigned NOT NULL DEFAULT '0',
`toStory` mediumint(8) NOT NULL DEFAULT '0',
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`severity` tinyint(4) NOT NULL default '0',
`severity` tinyint(4) NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
`type` varchar(30) NOT NULL default '',
`os` varchar(255) NOT NULL default '',
`browser` varchar(255) NOT NULL default '',
`type` varchar(30) NOT NULL DEFAULT '',
`os` varchar(255) NOT NULL DEFAULT '',
`browser` varchar(255) NOT NULL DEFAULT '',
`hardware` varchar(30) NOT NULL,
`found` varchar(30) NOT NULL default '',
`found` varchar(30) NOT NULL DEFAULT '',
`steps` mediumtext NOT NULL,
`status` enum('active','resolved','closed') NOT NULL default 'active',
`subStatus` varchar(30) NOT NULL default '',
`status` enum('active','resolved','closed') NOT NULL DEFAULT 'active',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`confirmed` tinyint(1) NOT NULL default '0',
`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 '',
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`assignedTo` varchar(30) NOT NULL default '',
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`resolvedBy` varchar(30) NOT NULL default '',
`resolution` varchar(30) NOT NULL default '',
`resolvedBuild` varchar(30) NOT NULL default '',
`resolvedBy` varchar(30) NOT NULL DEFAULT '',
`resolution` varchar(30) NOT NULL DEFAULT '',
`resolvedBuild` varchar(30) NOT NULL DEFAULT '',
`resolvedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL default '',
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`duplicateBug` mediumint(8) unsigned NOT NULL,
`linkBug` varchar(255) NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`caseVersion` smallint(6) NOT NULL DEFAULT '1',
`feedback` mediumint(8) unsigned NOT NULL DEFAULT '0',
`result` mediumint(8) unsigned NOT NULL,
`repo` mediumint(8) unsigned NOT NULL,
`mr` mediumint(8) unsigned NOT NULL,
@@ -302,9 +306,9 @@ CREATE TABLE IF NOT EXISTS `zt_bug` (
`repoType` varchar(30) NOT NULL DEFAULT '',
`issueKey` varchar(50) NOT NULL DEFAULT '',
`testtask` mediumint(8) unsigned NOT NULL,
`lastEditedBy` varchar(30) NOT NULL default '',
`lastEditedBy` varchar(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `execution` (`execution`),
@@ -618,21 +622,36 @@ CREATE TABLE IF NOT EXISTS `zt_designspec` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_doc`;
CREATE TABLE IF NOT EXISTS `zt_doc` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`project` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`execution` mediumint(8) unsigned NOT NULL,
`lib` varchar(30) NOT NULL,
`template` varchar(30) NOT NULL,
`templateType` varchar(30) NOT NULL,
`chapterType` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`status` varchar(30) NOT NULL,
`parent` smallint(5) unsigned NOT NULL DEFAULT '0',
`path` char(255) NOT NULL DEFAULT '',
`grade` tinyint(3) unsigned NOT NULL DEFAULT '0',
`order` smallint(5) unsigned NOT NULL DEFAULT '0',
`views` smallint(5) unsigned NOT NULL,
`assetLib` mediumint(8) unsigned NOT NULL DEFAULT '0',
`assetLibType` varchar(30) NOT NULL DEFAULT '',
`from` mediumint(8) unsigned NOT NULL DEFAULT '0',
`fromVersion` smallint(6) NOT NULL DEFAULT '1',
`draft` longtext NOT NULL,
`collector` text NOT NULL,
`addedBy` varchar(30) NOT NULL,
`addedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`assignedDate` datetime NOT NULL,
`approvedDate` date NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`mailto` text,
@@ -640,7 +659,7 @@ CREATE TABLE IF NOT EXISTS `zt_doc` (
`groups` varchar(255) NOT NULL,
`users` text NOT NULL,
`version` smallint(5) unsigned NOT NULL DEFAULT '1',
`deleted` enum('0','1') NOT NULL default '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `execution` (`execution`),
@@ -683,20 +702,28 @@ CREATE TABLE IF NOT EXISTS `zt_doclib` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_effort`;
CREATE TABLE IF NOT EXISTS `zt_effort` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(30) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`product` text NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`execution` mediumint(8) unsigned NOT NULL,
`account` varchar(30) NOT NULL,
`work` text,
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`user` char(30) NOT NULL default '',
`todo` enum('1','0') NOT NULL default '1',
`date` date NOT NULL,
`begin` datetime NOT NULL default '0000-00-00 00:00:00',
`end` datetime NOT NULL default '0000-00-00 00:00:00',
`type` enum('1','2','3') NOT NULL default '1',
`idvalue` mediumint(8) unsigned NOT NULL default '0',
`name` char(30) NOT NULL default '',
`desc` char(255) NOT NULL default '',
`status` enum('1','2','3') NOT NULL default '1',
PRIMARY KEY (`id`),
KEY `user` (`user`)
`left` float NOT NULL,
`consumed` float NOT NULL,
`begin` smallint(4) unsigned zerofill NOT NULL,
`end` smallint(4) unsigned zerofill NOT NULL,
`extra` text,
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `execution` (`execution`),
KEY `objectID` (`objectID`),
KEY `date` (`date`),
KEY `account` (`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_entry`;
CREATE TABLE IF NOT EXISTS `zt_entry` (
@@ -751,32 +778,33 @@ CREATE TABLE IF NOT EXISTS `zt_extension` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_file`;
CREATE TABLE IF NOT EXISTS `zt_file` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`pathname` char(50) NOT NULL,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`pathname` char(100) NOT NULL,
`title` varchar(255) NOT NULL,
`extension` char(30) NOT NULL,
`size` int(10) unsigned NOT NULL default '0',
`size` int(10) unsigned NOT NULL DEFAULT '0',
`objectType` char(30) NOT NULL,
`objectID` mediumint(9) NOT NULL,
`addedBy` char(30) NOT NULL default '',
`addedBy` char(30) NOT NULL DEFAULT '',
`addedDate` datetime NOT NULL,
`downloads` mediumint(8) unsigned NOT NULL default '0',
`downloads` mediumint(8) unsigned NOT NULL DEFAULT '0',
`extra` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `objectType` (`objectType`),
KEY `objectID` (`objectID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_group`;
CREATE TABLE IF NOT EXISTS `zt_group` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`project` mediumint(8) unsigned NOT NULL DEFAULT 0,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`name` char(30) NOT NULL,
`role` char(30) NOT NULL default '',
`desc` char(255) NOT NULL default '',
`role` char(30) NOT NULL DEFAULT '',
`desc` char(255) NOT NULL DEFAULT '',
`acl` text,
PRIMARY KEY (`id`)
`developer` enum('0','1') NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_grouppriv`;
CREATE TABLE IF NOT EXISTS `zt_grouppriv` (
@@ -1140,21 +1168,23 @@ CREATE TABLE IF NOT EXISTS `zt_planstory` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_product`;
CREATE TABLE IF NOT EXISTS `zt_product` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`program` mediumint(8) unsigned NOT NULL,
`name` varchar(110) NOT NULL,
`code` varchar(45) NOT NULL,
`shadow` tinyint(1) unsigned NOT NULL,
`bind` enum('0','1') NOT NULL DEFAULT '0',
`line` mediumint(8) NOT NULL,
`type` varchar(30) NOT NULL default 'normal',
`status` varchar(30) NOT NULL default '',
`subStatus` varchar(30) NOT NULL default '',
`type` varchar(30) NOT NULL DEFAULT 'normal',
`status` varchar(30) NOT NULL DEFAULT '',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`desc` mediumtext NOT NULL,
`PO` varchar(30) NOT NULL,
`QD` varchar(30) NOT NULL,
`RD` varchar(30) NOT NULL,
`acl` enum('open','private','custom') NOT NULL default 'open',
`feedback` varchar(30) NOT NULL,
`ticket` varchar(30) NOT NULL,
`acl` enum('open','private','custom') NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`reviewer` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
@@ -1162,7 +1192,7 @@ CREATE TABLE IF NOT EXISTS `zt_product` (
`createdVersion` varchar(20) NOT NULL,
`order` mediumint(8) unsigned NOT NULL,
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`deleted` enum('0','1') NOT NULL default '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `acl` (`acl`),
KEY `order` (`order`)
@@ -1483,39 +1513,44 @@ CREATE TABLE IF NOT EXISTS `zt_stakeholder` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_story`;
CREATE TABLE IF NOT EXISTS `zt_story` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`parent` mediumint(9) NOT NULL default '0',
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`module` mediumint(8) unsigned NOT NULL default '0',
`parent` mediumint(9) NOT NULL DEFAULT '0',
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`plan` text,
`source` varchar(20) NOT NULL,
`sourceNote` varchar(255) NOT NULL,
`fromBug` mediumint(8) unsigned NOT NULL default '0',
`fromBug` mediumint(8) unsigned NOT NULL DEFAULT '0',
`feedback` mediumint(8) unsigned NOT NULL DEFAULT '0',
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL default 'story',
`category` varchar(30) NOT NULL default 'feature',
`pri` tinyint(3) unsigned NOT NULL default '3',
`type` varchar(30) NOT NULL DEFAULT 'story',
`category` varchar(30) NOT NULL DEFAULT 'feature',
`pri` tinyint(3) unsigned NOT NULL DEFAULT '3',
`estimate` float unsigned NOT NULL,
`status` enum('','changing','active','draft', 'reviewing', 'closed') NOT NULL default '',
`subStatus` varchar(30) NOT NULL default '',
`status` enum('','changing','active','draft','reviewing','closed') NOT NULL DEFAULT '',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released', 'closed') NOT NULL DEFAULT 'wait',
`stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released','closed') NOT NULL DEFAULT 'wait',
`stagedBy` char(30) NOT NULL,
`mailto` text,
`openedBy` varchar(30) NOT NULL default '',
`lib` mediumint(8) unsigned NOT NULL DEFAULT '0',
`fromStory` mediumint(8) unsigned NOT NULL DEFAULT '0',
`fromVersion` smallint(6) NOT NULL DEFAULT '1',
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL default '',
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`lastEditedBy` varchar(30) NOT NULL default '',
`approvedDate` date NOT NULL,
`lastEditedBy` varchar(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`changedBy` VARCHAR(30) NOT NULL,
`changedDate` DATETIME NOT NULL,
`changedBy` varchar(30) NOT NULL,
`changedDate` datetime NOT NULL,
`reviewedBy` varchar(255) NOT NULL,
`reviewedDate` datetime NOT NULL default '0000-00-00 00:00:00',
`closedBy` varchar(30) NOT NULL default '',
`reviewedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`activatedDate` datetime NOT NULL,
@@ -1525,12 +1560,13 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
`linkRequirements` varchar(255) NOT NULL,
`twins` varchar(255) NOT NULL,
`duplicateStory` mediumint(8) unsigned NOT NULL,
`version` smallint(6) NOT NULL default '1',
`version` smallint(6) NOT NULL DEFAULT '1',
`storyChanged` enum('0','1') NOT NULL DEFAULT '0',
`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`),
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `status` (`status`),
KEY `assignedTo` (`assignedTo`)
@@ -1583,27 +1619,28 @@ CREATE TABLE IF NOT EXISTS `zt_suitecase` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_task`;
CREATE TABLE IF NOT EXISTS `zt_task` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`project` mediumint(8) unsigned NOT NULL,
`parent` mediumint(8) NOT NULL DEFAULT '0',
`execution` mediumint(8) unsigned NOT NULL default '0',
`module` mediumint(8) unsigned NOT NULL default '0',
`execution` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`design` mediumint(8) unsigned NOT NULL,
`story` mediumint(8) unsigned NOT NULL default '0',
`storyVersion` smallint(6) NOT NULL default '1',
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`designVersion` smallint(6) unsigned NOT NULL,
`fromBug` mediumint(8) unsigned NOT NULL default '0',
`fromIssue` mediumint(8) unsigned NOT NULL default '0',
`fromBug` mediumint(8) unsigned NOT NULL DEFAULT '0',
`feedback` mediumint(8) unsigned NOT NULL,
`fromIssue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`type` varchar(20) NOT NULL,
`mode` varchar(10) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL default '0',
`pri` tinyint(3) unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`deadline` date NOT NULL,
`status` enum('wait','doing','done','pause','cancel','closed') NOT NULL default 'wait',
`subStatus` varchar(30) NOT NULL default '',
`status` enum('wait','doing','done','pause','cancel','closed') NOT NULL DEFAULT 'wait',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`mailto` text,
`desc` mediumtext NOT NULL,
@@ -1634,7 +1671,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
`lines` varchar(10) NOT NULL,
`v1` varchar(40) NOT NULL,
`v2` varchar(40) NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
PRIMARY KEY (`id`),
KEY `execution` (`execution`),
@@ -1681,22 +1718,23 @@ CREATE TABLE `zt_taskteam` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_team`;
CREATE TABLE IF NOT EXISTS `zt_team` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`root` mediumint(8) unsigned NOT NULL default '0',
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`root` mediumint(8) unsigned NOT NULL DEFAULT '0',
`type` enum('project','task','execution') NOT NULL DEFAULT 'project',
`account` char(30) NOT NULL default '',
`role` char(30) NOT NULL default '',
`limited` char(8) NOT NULL default 'no',
`join` date NOT NULL default '0000-00-00',
`account` char(30) NOT NULL DEFAULT '',
`role` char(30) NOT NULL DEFAULT '',
`position` varchar(30) NOT NULL,
`limited` char(8) NOT NULL DEFAULT 'no',
`join` date NOT NULL DEFAULT '0000-00-00',
`days` smallint(5) unsigned NOT NULL,
`hours` float(3,1) unsigned NOT NULL default '0',
`estimate` DECIMAL(12,2) UNSIGNED NOT NULL DEFAULT '0',
`consumed` DECIMAL(12,2) UNSIGNED NOT NULL DEFAULT '0',
`left` DECIMAL(12,2) UNSIGNED NOT NULL DEFAULT '0',
`order` TINYINT(3) NOT NULL DEFAULT '0',
`hours` float(3,1) unsigned NOT NULL DEFAULT '0.0',
`estimate` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`consumed` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`left` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`order` tinyint(3) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `team` (`root`,`type`,`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_testreport`;
CREATE TABLE IF NOT EXISTS `zt_testreport` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
@@ -1723,7 +1761,7 @@ CREATE TABLE IF NOT EXISTS `zt_testreport` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_testresult`;
CREATE TABLE IF NOT EXISTS `zt_testresult` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`run` mediumint(8) unsigned NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`version` smallint(5) unsigned NOT NULL,
@@ -1737,7 +1775,8 @@ CREATE TABLE IF NOT EXISTS `zt_testresult` (
`date` datetime NOT NULL,
`duration` float NOT NULL,
`xml` text NOT NULL,
PRIMARY KEY (`id`),
`deploy` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `case` (`case`),
KEY `version` (`version`),
KEY `run` (`run`)
@@ -1808,7 +1847,8 @@ CREATE TABLE IF NOT EXISTS `zt_todo` (
`date` date NOT NULL,
`begin` smallint(4) unsigned zerofill NOT NULL,
`end` smallint(4) unsigned zerofill NOT NULL,
`type` char(10) NOT NULL,
`feedback` mediumint(8) unsigned NOT NULL,
`type` char(15) NOT NULL,
`cycle` tinyint(3) unsigned NOT NULL DEFAULT '0',
`idvalue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
@@ -1824,7 +1864,7 @@ CREATE TABLE IF NOT EXISTS `zt_todo` (
`finishedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
PRIMARY KEY (`id`),
KEY `account` (`account`),
@@ -1834,46 +1874,51 @@ CREATE TABLE IF NOT EXISTS `zt_todo` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_user`;
CREATE TABLE IF NOT EXISTS `zt_user` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`company` mediumint unsigned NOT NULL,
`type` char(30) NOT NULL default 'inside',
`dept` mediumint(8) unsigned NOT NULL default '0',
`account` char(30) NOT NULL default '',
`password` char(32) NOT NULL default '',
`role` char(10) NOT NULL default '',
`realname` varchar(100) NOT NULL default '',
`nickname` char(60) NOT NULL default '',
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`company` mediumint(8) unsigned NOT NULL,
`type` char(30) NOT NULL DEFAULT 'inside',
`dept` mediumint(8) unsigned NOT NULL DEFAULT '0',
`account` char(30) NOT NULL DEFAULT '',
`password` char(32) NOT NULL DEFAULT '',
`role` char(10) NOT NULL DEFAULT '',
`realname` varchar(100) NOT NULL DEFAULT '',
`pinyin` varchar(255) NOT NULL DEFAULT '',
`nickname` char(60) NOT NULL DEFAULT '',
`commiter` varchar(100) NOT NULL,
`avatar` text NOT NULL,
`birthday` date NOT NULL default '0000-00-00',
`gender` enum('f','m') NOT NULL default 'f',
`email` char(90) NOT NULL default '',
`skype` char(90) NOT NULL default '',
`qq` char(20) NOT NULL default '',
`mobile` char(11) NOT NULL default '',
`phone` char(20) NOT NULL default '',
`weixin` varchar(90) NOT NULL default '',
`dingding` varchar(90) NOT NULL default '',
`slack` varchar(90) NOT NULL default '',
`whatsapp` varchar(90) NOT NULL default '',
`address` char(120) NOT NULL default '',
`zipcode` char(10) NOT NULL default '',
`birthday` date NOT NULL DEFAULT '0000-00-00',
`gender` enum('f','m') NOT NULL DEFAULT 'f',
`email` char(90) NOT NULL DEFAULT '',
`skype` char(90) NOT NULL DEFAULT '',
`qq` char(20) NOT NULL DEFAULT '',
`mobile` char(11) NOT NULL DEFAULT '',
`phone` char(20) NOT NULL DEFAULT '',
`weixin` varchar(90) NOT NULL DEFAULT '',
`dingding` varchar(90) NOT NULL DEFAULT '',
`slack` varchar(90) NOT NULL DEFAULT '',
`whatsapp` varchar(90) NOT NULL DEFAULT '',
`address` char(120) NOT NULL DEFAULT '',
`zipcode` char(10) NOT NULL DEFAULT '',
`nature` text NOT NULL,
`analysis` text NOT NULL,
`strategy` text NOT NULL,
`join` date NOT NULL default '0000-00-00',
`visits` mediumint(8) unsigned NOT NULL default '0',
`join` date NOT NULL DEFAULT '0000-00-00',
`visits` mediumint(8) unsigned NOT NULL DEFAULT '0',
`visions` varchar(20) NOT NULL DEFAULT 'rnd,lite',
`ip` char(15) NOT NULL default '',
`last` int(10) unsigned NOT NULL default '0',
`fails` tinyint(5) NOT NULL default '0',
`locked` datetime NOT NULL default '0000-00-00 00:00:00',
`ranzhi` char(30) NOT NULL default '',
`score` INT(11) NOT NULL DEFAULT '0',
`scoreLevel` INT(11) NOT NULL DEFAULT '0',
`ip` char(15) NOT NULL DEFAULT '',
`last` int(10) unsigned NOT NULL DEFAULT '0',
`fails` tinyint(5) NOT NULL DEFAULT '0',
`locked` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`feedback` enum('0','1') NOT NULL DEFAULT '0',
`ranzhi` char(30) NOT NULL DEFAULT '',
`ldap` char(30) NOT NULL,
`score` int(11) NOT NULL DEFAULT '0',
`scoreLevel` int(11) NOT NULL DEFAULT '0',
`resetToken` varchar(50) NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`clientStatus` enum('online','away','busy','offline','meeting') NOT NULL DEFAULT 'offline',
`clientLang` varchar(10) NOT NULL DEFAULT 'zh-cn',
PRIMARY KEY (`id`),
UNIQUE KEY `account` (`account`),
KEY `dept` (`dept`),
KEY `email` (`email`),
@@ -6384,7 +6429,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat` (
`lastMessageIndex` int(11) unsigned NOT NULL DEFAULT 0,
`dismissDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`pinnedMessages` text NOT NULL DEFAULT '',
`mergedChats` text NOT NULL DEFAULT '',
`mergedChats` text NOT NULL,
`adminInvite` enum('0','1') NOT NULL DEFAULT '0',
`avatar` text NOT NULL DEFAULT '',
`archiveDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -6573,39 +6618,6 @@ CREATE TABLE IF NOT EXISTS `zt_im_userdevice` (
UNIQUE KEY `userdevice` (`user`, `device`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_file` CHANGE `pathname` `pathname` char(100) NOT NULL;
ALTER TABLE `zt_user` ADD `clientStatus` enum('online', 'away', 'busy', 'offline', 'meeting') NOT NULL DEFAULT 'offline';
ALTER TABLE `zt_user` ADD `clientLang` varchar(10) NOT NULL DEFAULT 'zh-cn';
ALTER TABLE `zt_user` ADD `pinyin` varchar(255) NOT NULL DEFAULT '' AFTER `realname`;
ALTER TABLE `zt_effort` DROP INDEX `user`;
ALTER TABLE `zt_effort` DROP `user`;
ALTER TABLE `zt_effort` DROP `todo`;
ALTER TABLE `zt_effort` DROP `type`;
ALTER TABLE `zt_effort` DROP `idvalue`;
ALTER TABLE `zt_effort` DROP `name`;
ALTER TABLE `zt_effort` DROP `desc`;
ALTER TABLE `zt_effort` DROP `status`;
ALTER TABLE `zt_effort` ADD `objectType` varchar(30) NOT NULL AFTER `id`;
ALTER TABLE `zt_effort` ADD `objectID` mediumint(8) unsigned NOT NULL AFTER `objectType`;
ALTER TABLE `zt_effort` ADD `product` text NOT NULL AFTER `objectID`;
ALTER TABLE `zt_effort` ADD `project` mediumint(8) unsigned NOT NULL AFTER `product`;
ALTER TABLE `zt_effort` ADD `execution` mediumint(8) unsigned NOT NULL AFTER `project`;
ALTER TABLE `zt_effort` ADD `account` varchar(30) NOT NULL AFTER `execution`;
ALTER TABLE `zt_effort` ADD `work` text COLLATE 'utf8_general_ci' NULL AFTER `account`;
ALTER TABLE `zt_effort` ADD `left` float NOT NULL AFTER `date`;
ALTER TABLE `zt_effort` ADD `consumed` float NOT NULL AFTER `left`;
ALTER TABLE `zt_effort` CHANGE `begin` `begin` smallint(4) unsigned zerofill NOT NULL AFTER `consumed`;
ALTER TABLE `zt_effort` CHANGE `end` `end` smallint(4) unsigned zerofill NOT NULL AFTER `begin`;
ALTER TABLE `zt_effort` ADD `deleted` enum('0','1') NOT NULL DEFAULT '0' AFTER `end`;
ALTER TABLE `zt_effort` ADD `order` tinyint unsigned NOT NULL DEFAULT '0' AFTER `end`;
ALTER TABLE `zt_effort` ADD `extra` text COLLATE 'utf8_general_ci' NULL AFTER `end`;
ALTER TABLE `zt_effort` ADD INDEX `execution` (`execution`);
ALTER TABLE `zt_effort` ADD INDEX `objectID` (`objectID`);
ALTER TABLE `zt_effort` ADD INDEX `date` (`date`);
ALTER TABLE `zt_effort` ADD INDEX `account` (`account`);
ALTER TABLE `zt_action` ADD `efforted` BOOL NOT NULL DEFAULT '0';
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('30', '23', '*', '*', '*', 'moduleName=execution&methodName=computeTaskEffort', '计算任务剩余工时', 'zentao', '1', 'normal', '0000-00-00 00:00:00');
INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('30', '7', '*', '*', '*', 'moduleName=effort&methodName=remindNotRecord', '提醒录入日志', 'zentao', '1', 'stop', '0000-00-00 00:00:00');
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
@@ -7028,7 +7040,6 @@ REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(11,'report','testcase'),
(11,'report','workAssignSummary'),
(11,'report','workSummary');
ALTER TABLE `zt_user` ADD `ldap` CHAR(30) NOT NULL AFTER `ranzhi`;
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1,'ldap','index'),
@@ -7216,7 +7227,7 @@ CREATE TABLE IF NOT EXISTS `zt_ticket` (
`finishedDate` datetime NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`resolvedDate` datetime NOT NULL,
`resolution` varchar(1000) NOT NULL,
`resolution` text NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`keywords` varchar(255) NOT NULL,
@@ -7249,11 +7260,6 @@ CREATE TABLE IF NOT EXISTS `zt_ticketrelation` (
KEY `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_bug` ADD `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `caseVersion`;
ALTER TABLE `zt_story` ADD `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `fromBug`;
ALTER TABLE `zt_user` ADD `feedback` enum('0', '1') NOT NULL DEFAULT '0' AFTER `locked`;
ALTER TABLE `zt_group` ADD `developer` enum('0', '1') NOT NULL DEFAULT '1' AFTER `acl`;
-- DROP TABLE IF EXISTS `zt_feedbackproduct`;
CREATE TABLE IF NOT EXISTS `zt_feedbackview` (
`account` char(30) NOT NULL,
@@ -7485,6 +7491,9 @@ CREATE TABLE IF NOT EXISTS `zt_overtime` (
`createdDate` datetime NOT NULL,
`reviewedBy` char(30) NOT NULL,
`reviewedDate` datetime NOT NULL,
`level` tinyint(3) NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`reviewers` text NOT NULL,
PRIMARY KEY (`id`),
KEY `year` (`year`),
KEY `type` (`type`),
@@ -7521,6 +7530,10 @@ CREATE TABLE IF NOT EXISTS `zt_leave` (
`createdDate` datetime NOT NULL,
`reviewedBy` char(30) NOT NULL,
`reviewedDate` datetime NOT NULL,
`level` tinyint(3) NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`reviewers` text NOT NULL,
`backReviewers` text NOT NULL,
PRIMARY KEY (`id`),
KEY `year` (`year`),
KEY `type` (`type`),
@@ -7544,6 +7557,9 @@ CREATE TABLE IF NOT EXISTS `zt_lieu` (
`createdDate` datetime NOT NULL,
`reviewedBy` char(30) NOT NULL,
`reviewedDate` datetime NOT NULL,
`level` tinyint(3) NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`reviewers` text NOT NULL,
PRIMARY KEY (`id`),
KEY `year` (`year`),
KEY `status` (`status`),
@@ -7615,7 +7631,6 @@ CREATE TABLE IF NOT EXISTS `zt_deploystep` (
`deleted` enum('0','1') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_testresult` ADD `deploy` mediumint(8) unsigned NOT NULL;
-- DROP TABLE IF EXISTS `zt_deployscope`;
CREATE TABLE IF NOT EXISTS `zt_deployscope` (
`deploy` mediumint(8) unsigned NOT NULL,
@@ -7684,26 +7699,6 @@ CREATE TABLE IF NOT EXISTS `zt_trainrecords` (
PRIMARY KEY (`user`, `objectId`, `objectType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_doc`
ADD `parent` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `type`,
ADD `path` char(255) COLLATE 'utf8_general_ci' NOT NULL DEFAULT '' AFTER `parent`,
ADD `grade` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `path`,
ADD `order` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `grade`;
ALTER TABLE `zt_product` ADD `feedback` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `RD`;
ALTER TABLE `zt_product` ADD `ticket` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `feedback`;
ALTER TABLE `zt_leave` ADD `level` tinyint(3) NOT NULL;
ALTER TABLE `zt_leave` ADD `assignedTo` varchar(30) NOT NULL;
ALTER TABLE `zt_leave` ADD `reviewers` text NOT NULL;
ALTER TABLE `zt_leave` ADD `backReviewers` text NOT NULL;
ALTER TABLE `zt_lieu` ADD `level` tinyint(3) NOT NULL;
ALTER TABLE `zt_lieu` ADD `assignedTo` varchar(30) NOT NULL;
ALTER TABLE `zt_lieu` ADD `reviewers` text NOT NULL;
ALTER TABLE `zt_overtime` ADD `level` tinyint(3) NOT NULL;
ALTER TABLE `zt_overtime` ADD `assignedTo` varchar(30) NOT NULL;
ALTER TABLE `zt_overtime` ADD `reviewers` text NOT NULL;
-- DROP TABLE IF EXISTS `zt_faq`;
CREATE TABLE IF NOT EXISTS `zt_faq` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
@@ -7715,9 +7710,6 @@ CREATE TABLE IF NOT EXISTS `zt_faq` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_task` ADD `feedback` mediumint(8) unsigned NOT NULL AFTER `fromBug`;
ALTER TABLE `zt_todo` ADD `feedback` mediumint(8) unsigned NOT NULL AFTER `end`;
-- DROP TABLE IF EXISTS `zt_domain`;
CREATE TABLE IF NOT EXISTS `zt_domain`(
`id` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -8744,6 +8736,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflow` (
`parent` varchar(30) NOT NULL,
`child` varchar(30) NOT NULL,
`type` varchar(10) NOT NULL DEFAULT 'flow',
`navigator` varchar(10) NOT NULL,
`app` varchar(20) NOT NULL,
`position` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
@@ -8760,17 +8753,18 @@ CREATE TABLE IF NOT EXISTS `zt_workflow` (
`desc` text NOT NULL,
`version` varchar(10) NOT NULL DEFAULT '1.0',
`status` varchar(10) NOT NULL DEFAULT 'wait',
`approval` enum('enabled', 'disabled') NOT NULL DEFAULT 'disabled',
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`approval` enum('enabled','disabled') NOT NULL DEFAULT 'disabled',
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
PRIMARY KEY `id` (`id`),
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`app`,`module`,`vision`),
KEY `type` (`type`),
KEY `app` (`app`),
KEY `module` (`module`),
KEY `order` (`order`),
UNIQUE KEY `unique` (`app`, `module`)
KEY `order` (`order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_workflowaction`;
@@ -8780,13 +8774,13 @@ CREATE TABLE IF NOT EXISTS `zt_workflowaction` (
`action` varchar(50) NOT NULL,
`method` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL,
`type` enum('single', 'batch') NOT NULL DEFAULT 'single',
`batchMode` enum('same', 'different') NOT NULL DEFAULT 'different',
`type` enum('single','batch') NOT NULL DEFAULT 'single',
`batchMode` enum('same','different') NOT NULL DEFAULT 'different',
`extensionType` varchar(10) NOT NULL DEFAULT 'override' COMMENT 'none | extend | override',
`open` varchar(20) NOT NULL,
`position` enum('menu', 'browseandview', 'browse', 'view') NOT NULL DEFAULT 'browseandview',
`position` enum('menu','browseandview','browse','view') NOT NULL DEFAULT 'browseandview',
`layout` char(20) NOT NULL,
`show` enum('dropdownlist', 'direct') NOT NULL DEFAULT 'dropdownlist',
`show` enum('dropdownlist','direct') NOT NULL DEFAULT 'dropdownlist',
`order` smallint(5) unsigned NOT NULL,
`buildin` tinyint(1) unsigned NOT NULL,
`role` varchar(10) NOT NULL DEFAULT 'custom',
@@ -8801,21 +8795,22 @@ CREATE TABLE IF NOT EXISTS `zt_workflowaction` (
`blocks` text NOT NULL,
`desc` text NOT NULL,
`status` varchar(10) NOT NULL DEFAULT 'enable',
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
PRIMARY KEY `id` (`id`),
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`module`,`action`,`vision`),
KEY `module` (`module`),
KEY `action` (`action`),
KEY `order` (`order`),
UNIQUE KEY `unique` (`module`, `action`)
KEY `order` (`order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_workflowdatasource`;
CREATE TABLE IF NOT EXISTS `zt_workflowdatasource` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`type` enum('system', 'sql', 'func', 'option', 'lang', 'category') NOT NULL DEFAULT 'option',
`type` enum('system','sql','func','option','lang','category') NOT NULL DEFAULT 'option',
`name` varchar(30) NOT NULL,
`code` varchar(30) NOT NULL,
`datasource` text NOT NULL,
@@ -8823,6 +8818,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowdatasource` (
`keyField` varchar(50) NOT NULL,
`valueField` varchar(50) NOT NULL,
`buildin` tinyint(1) unsigned NOT NULL,
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`createdBy` char(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` char(30) NOT NULL,
@@ -8871,20 +8867,21 @@ CREATE TABLE IF NOT EXISTS `zt_workflowlayout` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`module` varchar(30) NOT NULL,
`action` varchar(50) NOT NULL,
`field` varchar(50) NOT NULL,
`field` varchar(50) NOT NULL,
`order` smallint(5) unsigned NOT NULL,
`width` smallint(5) NOT NULL,
`position` text NOT NULL,
`readonly` enum('0', '1') NOT NULL DEFAULT '0',
`mobileShow` enum('0', '1') NOT NULL DEFAULT '1',
`readonly` enum('0','1') NOT NULL DEFAULT '0',
`mobileShow` enum('0','1') NOT NULL DEFAULT '1',
`summary` varchar(20) NOT NULL,
`defaultValue` text NOT NULL,
`layoutRules` varchar(255) NOT NULL,
PRIMARY KEY `id` (`id`),
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`module`,`action`,`field`,`vision`),
KEY `module` (`module`),
KEY `action` (`action`),
KEY `order` (`order`),
UNIQUE KEY `unique` (`module`, `action`, `field`)
KEY `order` (`order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_workflowlabel`;
@@ -9014,10 +9011,6 @@ CREATE TABLE IF NOT EXISTS `zt_workflowreport` (
PRIMARY KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_action` CHANGE `action` `action` varchar(80) NOT NULL DEFAULT '';
ALTER TABLE `zt_action` CHANGE `extra` `extra` text;
ALTER TABLE `zt_file` CHANGE `objectType` `objectType` char(30) NOT NULL;
REPLACE INTO `zt_workflowrule` VALUES (1,'system','必填','notempty','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00'),(2,'system','唯一','unique','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00'),(3,'system','日期','date','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00'),(4,'system','email','email','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00'),(5,'system','数字','float','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00'),(6,'system','电话','phone','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00'),(7,'system','IP','ip','admin','2020-10-14 14:06:14','','0000-00-00 00:00:00');
REPLACE INTO `zt_grouppriv` VALUES
@@ -9095,19 +9088,6 @@ REPLACE INTO `zt_grouppriv` VALUES
(1,'workflowrule','edit'),
(1,'workflowrule','view');
ALTER TABLE `zt_workflow` ADD `navigator` varchar(10) NOT NULL AFTER `type`;
ALTER TABLE `zt_workflow` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `status`;
ALTER TABLE `zt_workflowdatasource` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `buildin`;
ALTER TABLE `zt_workflowaction` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `status`;
ALTER TABLE `zt_workflowlayout` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd';
ALTER TABLE `zt_workflow` DROP INDEX `unique`;
ALTER TABLE `zt_workflow` ADD UNIQUE `unique` (`app`, `module`, `vision`);
ALTER TABLE `zt_workflowaction` DROP INDEX `unique`;
ALTER TABLE `zt_workflowaction` ADD UNIQUE `unique` (`module`, `action`, `vision`);
ALTER TABLE `zt_workflowlayout` DROP INDEX `unique`;
ALTER TABLE `zt_workflowlayout` ADD UNIQUE `unique` (`module`, `action`, `field`, `vision`);
INSERT INTO `zt_workflowdatasource` (`type`, `name`, `code`, `buildin`, `datasource`, `view`, `keyField`, `valueField`) VALUES
('system', '产品', 'products', '1', '{\"app\":\"system\",\"module\":\"product\",\"method\":\"getPairs\",\"methodDesc\":\"Get product pairs.\",\"params\":[{\"name\":\"mode\",\"type\":\"string\",\"desc\":\"\",\"value\":\"all\"}]}', '', '', ''),
('system', '项目', 'projects', '1', '{\"app\":\"system\",\"module\":\"project\",\"method\":\"getPairsByModel\",\"methodDesc\":\"Get project pairs by model and project.\",\"params\":[{\"name\":\"model\",\"type\":\"string\",\"desc\":\"all|scrum|waterfall\",\"value\":\"all\"},{\"name\":\"programID\",\"type\":\"int\",\"desc\":\"\",\"value\":\"0\"},{\"name\":\"param\",\"type\":\"\",\"desc\":\"\",\"value\":\"\"}]}', '', '', ''),
@@ -9199,26 +9179,6 @@ CREATE VIEW `view_datasource_12` AS select `id`,`title` from `zt_productplan` wh
CREATE VIEW `view_datasource_41` AS select `id`,`title` from `zt_case` where `deleted` = '0';
CREATE VIEW `view_datasource_54` AS select `id`,`name` from `zt_task` where `deleted` = '0' and vision = 'lite';
ALTER TABLE `zt_doc` ADD `template` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `lib`;
ALTER TABLE `zt_doc` ADD `templateType` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `template`;
ALTER TABLE `zt_doc` ADD `chapterType` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `templateType`;
ALTER TABLE `zt_doc` ADD `assetLib` mediumint(8) unsigned NOT NULL default 0 after `views`;
ALTER TABLE `zt_doc` ADD `assetLibType` varchar(30) NOT NULL default '' after `assetLib`;
ALTER TABLE `zt_doc` ADD `from` mediumint(8) unsigned NOT NULL default 0 after `assetLibType`;
ALTER TABLE `zt_doc` ADD `fromVersion` smallint(6) NOT NULL default 1 after `from`;
ALTER TABLE `zt_doc` ADD `assignedTo` varchar(30) NOT NULL after `addedDate`;
ALTER TABLE `zt_doc` ADD `assignedDate` datetime NOT NULL after `assignedTo`;
ALTER TABLE `zt_doc` ADD `approvedDate` date NOT NULL after `assignedDate`;
ALTER TABLE `zt_doc` ADD `status` varchar(30) NOT NULL after `type`;
ALTER TABLE `zt_story` ADD `storyChanged` enum('0','1') NOT NULL DEFAULT '0' AFTER `version`;
ALTER TABLE `zt_story` ADD `lib` mediumint(8) unsigned NOT NULL default 0 after `mailto`;
ALTER TABLE `zt_story` ADD `fromStory` mediumint(8) unsigned NOT NULL default 0 after `lib`;
ALTER TABLE `zt_story` ADD `fromVersion` smallint(6) NOT NULL default 1 after `fromStory`;
ALTER TABLE `zt_story` ADD `approvedDate` date NOT NULL after `assignedDate`;
ALTER TABLE `zt_todo` MODIFY COLUMN `type` char(15) NOT NULL;
-- DROP TABLE IF EXISTS `zt_durationestimation`;
CREATE TABLE IF NOT EXISTS `zt_durationestimation` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
@@ -10032,12 +9992,6 @@ CREATE TABLE IF NOT EXISTS `zt_gapanalysis` (
UNIQUE KEY `project_account` (`project`,`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_bug`
ADD `injection` mediumint(8) unsigned NOT NULL AFTER `product`,
ADD `identify` mediumint(8) unsigned NOT NULL AFTER `injection`;
ALTER TABLE `zt_team` ADD `position` varchar(30) not null AFTER role;
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1,'activity','assignTo'),
(1,'activity','batchCreate'),
+1 -1
View File
@@ -1930,7 +1930,7 @@
23560 项目-测试用例列表有报错
2022-06-02 17.0
修复的bug
修复的Bug
22948 执行需求列表中列名称显示遮挡
22898 项目关闭导致该项目下执行所属项目自动变更了
22904 导入测试用例模板没有区分必填项
@@ -44,7 +44,7 @@ class myExecution extends execution
$TRActions .= "<ul id='kanbanActionMenu' class='dropdown-menu pull-right'>";
$width = $this->app->getClientLang() == 'en' ? '750' : '650';
if(common::hasPriv('kanban', 'createRegion')) $TRActions .= '<li>' . html::a(helper::createLink('kanban', 'createRegion', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-plus"></i>' . $this->lang->kanban->createRegion, '', "class='iframe btn btn-link text-left'") . '</li>';
if(common::hasPriv('kanban', 'setLaneHeight')) $TRActions .= '<li>' . html::a(helper::createLink('kanban', 'setLaneHeight', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-size-height"></i>' . $this->lang->kanban->laneHeight, '', "class='iframe btn btn-link text-left' data-width=$width") . '</li>';
if(common::hasPriv('execution', 'setKanban')) $TRActions .= '<li>' . html::a(helper::createLink('execution', 'setKanban', "kanbanID=$execution->id&from=execution", '', true), '<i class="icon icon-size-height"></i>' . $this->lang->kanban->laneHeight, '', "class='iframe btn btn-link text-left' data-width=$width") . '</li>';
$kanbanActions = '';
if(common::hasPriv('execution', 'edit')) $kanbanActions .= '<li>' . html::a(helper::createLink('execution', 'edit', "executionID=$execution->id", '', true), '<i class="icon icon-edit"></i>' . $this->lang->kanban->edit, '', "class='iframe btn btn-link text-left' data-width='75%'") . '</li>';
if(in_array('start', $executionActions)) $kanbanActions .= '<li>' . html::a(helper::createLink('execution', 'start', "executionID=$execution->id", '', true), '<i class="icon icon-play"></i>' . $this->lang->execution->start, '', "class='iframe btn btn-link text-left' data-width='75%'") . '</li>';
@@ -1,4 +1,9 @@
<?php
$config->project->list->exportFields = 'id,code,name,status,PM,desc';
$config->project->datatable->defaultField = array('id', 'name', 'status', 'PM', 'begin', 'end', 'progress', 'actions');
unset($config->project->datatable->fieldList['budget']);
unset($config->project->search['fields']['hasProduct']);
unset($config->project->search['fields']['parent']);
unset($config->project->search['fields']['model']);
@@ -14,6 +14,7 @@
<?php include $this->app->getModuleRoot() . '/common/view/datepicker.html.php';?>
<?php js::set('taskConsumed', $taskConsumed);?>
<?php js::set('addChildTask', $lang->task->addChildTask);?>
<?php js::set('isonlybody', isonlybody())?>
<?php js::set('regionID', $regionID);?>
<style>.c-lane,.c-region{width:150px;}</style>
<div id="mainContent" class="main-content fade">
+1 -1
View File
@@ -103,7 +103,7 @@
<tr>
<th><?php echo $lang->task->story;?></th>
<td colspan='3'>
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('story', 'create', "productID=$productID&branch=0&moduleID=0&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=story&_single"), $lang->execution->linkStory, '_blank', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
<span id='storyBox' class="<?php if(!empty($stories)) echo 'hidden';?> "><?php printf($lang->task->noticeLinkStory, html::a($this->createLink('story', 'create', "productID=$productID&branch=0&moduleID=0&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=story&_single"), $lang->execution->linkStory, '', 'class="text-primary"'), html::a("javascript:loadStories($execution->id)", $lang->refresh, '', 'class="text-primary"'));?></span>
<div class='input-group <?php if(empty($stories)) echo "hidden";?>'>
<?php echo html::select('story', $stories, $task->story, "class='form-control chosen' onchange='setStoryRelated();'");?>
<span class='input-group-btn' id='preview'><a href='#' class='btn iframe'><?php echo $lang->preview;?></a></span>
+1 -1
View File
@@ -481,7 +481,7 @@ class actionModel extends model
$name = $this->dao->select('name')->from(TABLE_TESTTASK)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = common::hasPriv('testtask', 'view') ? html::a(helper::createLink('testtask', 'view', "taskID=$action->extra"), $name) : $name;
}
elseif($action->objectType != 'feedback' and $actionName == 'tostory')
elseif(strpos('feedback,ticket', $action->objectType) === false and $actionName == 'tostory')
{
$title = $this->dao->select('title')->from(TABLE_STORY)->where('id')->eq($action->extra)->fetch('title');
if($title) $action->extra = common::hasPriv('story', 'view') ? html::a(helper::createLink('story', 'view', "storyID=$action->extra"), "#$action->extra " . $title) : "#$action->extra " . $title;
+6 -7
View File
@@ -93,12 +93,12 @@ class backup extends control
$backFileName = "{$this->backupPath}{$fileName}.sql";
if(!$nosafe) $backFileName .= '.php';
$result = $this->backup->backSQL($backFileName);
if(!$result->result)
{
if($reload == 'yes')
{
echo js::alert(sprintf($this->lang->backup->error->noWritable, $this->backupPath));
return print(js::reload('parent'));
return print(sprintf($this->lang->backup->error->noWritable, $this->backupPath));
}
else
{
@@ -112,12 +112,12 @@ class backup extends control
$backFileName = "{$this->backupPath}{$fileName}.file";
$result = $this->backup->backFile($backFileName);
if(!$result->result)
{
if($reload == 'yes')
{
echo js::alert(sprintf($this->lang->backup->error->backupFile, $result->error));
return print(js::reload('parent'));
return print(sprintf($this->lang->backup->error->backupFile, $result->error));
}
else
{
@@ -132,8 +132,7 @@ class backup extends control
{
if($reload == 'yes')
{
echo js::alert(sprintf($this->lang->backup->error->backupCode, $result->error));
return print(js::reload('parent'));
return print(sprintf($this->lang->backup->error->backupCode, $result->error));
}
else
{
@@ -164,7 +163,7 @@ class backup extends control
}
}
if($reload == 'yes') return print(js::reload('parent'));
if($reload == 'yes') return print($this->lang->backup->success->backup);
echo $this->lang->backup->success->backup . "\n";
}
+25 -1
View File
@@ -2,9 +2,32 @@ $(function()
{
$('.backup').click(function()
{
var timeID = null;
$.ajax({
url: $(this).attr('data-link'),
success: function(data)
{
clearInterval(timeID);
$('#waitting .modal-body #message').append(data);
setTimeout(function(){return location.reload();}, 2000);
},
error: function(request, textstatus, error)
{
clearInterval(timeID);
if(textstatus == 'timeout') $('#waitting .modal-body #message').append("<p class='text-danger'>" + backupTimeout + '</p>');
setTimeout(function(){return location.reload();}, 2000);
}
});
$('#waitting .modal-body #backupType').html(backup);
$('#waitting').modal('show');
setInterval(function()
timeID = setInterval(function()
{
$.get(createLink('backup', 'ajaxGetProgress'), function(data)
{
@@ -12,6 +35,7 @@ $(function()
});
}, 1000);
})
$('.rmPHPHeader').click(function()
{
$('#waitting .modal-body #backupType').html(rmPHPHeader);
+1
View File
@@ -48,3 +48,4 @@ $lang->backup->error->restoreSQL = "Datenbankwiederherstellung fehlgeschlagen.
$lang->backup->error->restoreFile = "Dateiwiederherstellung fehlgeschlagen. Error: %s.";
$lang->backup->error->backupFile = "Dateibackup fehlgeschlagen. Error: %s.";
$lang->backup->error->backupCode = "Codebackup fehlgeschlagen. Error: %s.";
$lang->backup->error->timeout = "Backup timeout.";
+1
View File
@@ -48,3 +48,4 @@ $lang->backup->error->restoreSQL = "Failed to restore the database library. Err
$lang->backup->error->restoreFile = "Failed to restore the file. Error %s.";
$lang->backup->error->backupFile = "Failed to back up the file. Error %s.";
$lang->backup->error->backupCode = "Failed to back up the code. Error %s.";
$lang->backup->error->timeout = "Backup timeout.";
+1
View File
@@ -48,3 +48,4 @@ $lang->backup->error->restoreSQL = "Echec pour restaurer la database library. E
$lang->backup->error->restoreFile = "Echec pour restaurer le fichier. Erreur %s.";
$lang->backup->error->backupFile = "Echec pour sauvegarder le fichier. Erreur %s.";
$lang->backup->error->backupCode = "Echec pour sauvegarder le code. Erreur %s.";
$lang->backup->error->timeout = "Backup timeout.";
+1
View File
@@ -48,3 +48,4 @@ $lang->backup->error->restoreSQL = "数据库还原失败,错误:%s";
$lang->backup->error->restoreFile = "附件还原失败,错误:%s";
$lang->backup->error->backupFile = "附件备份失败,错误:%s";
$lang->backup->error->backupCode = "代码备份失败,错误:%s";
$lang->backup->error->timeout = "备份超时";
+8 -1
View File
@@ -27,7 +27,13 @@
</h2>
<div class='pull-right'>
<?php common::printLink('backup', 'setting', '', "<i class='icon icon-cog'></i> " . $lang->backup->setting, '', "data-width='500' class='iframe btn btn-primary'");?>
<?php common::printLink('backup', 'backup', 'reload=yes', "<i class='icon icon-copy'></i> " . $lang->backup->backup, 'hiddenwin', "class='btn btn-primary backup'");?>
<?php
if(common::hasPriv('backup', 'backup'))
{
$backupLink = helper::createLink('backup', 'backup', 'reload=yes');
echo html::commonButton("<i class='icon icon-copy'> </i>" . $lang->backup->backup, "data-link='{$backupLink}'", 'btn btn-primary backup');
}
?>
</div>
</div>
<table class='table table-condensed table-bordered active-disabled table-fixed'>
@@ -114,4 +120,5 @@
<?php js::set('rmPHPHeader', $lang->backup->rmPHPHeader);?>
<?php js::set('confirmRestore', $lang->backup->confirmRestore);?>
<?php js::set('restore', $lang->backup->restore);?>
<?php js::set('backupTimeout', $lang->backup->error->timeout);?>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -277,7 +277,7 @@ class block extends control
/* The list assigned to me jumps to the work page when click more button. */
$block->moreLink = $this->createLink($moduleName, $method, $vars);
if($moduleName == 'my' and strpos($this->config->block->workMethods, $method))
if($moduleName == 'my' and strpos($this->config->block->workMethods, $method) !== false)
{
$block->moreLink = $this->createLink($moduleName, 'work', 'mode=' . $method . '&' . $vars);
}
+13 -18
View File
@@ -1,34 +1,29 @@
<div class='flowchart'>
<?php foreach ($lang->block->flowchart as $flowName => $flow):?>
<?php $idx = 0; ?>
<div class='row row-<?php echo $flowName?>'>
<div class='row flow-chart-row row-<?php echo $flowName?>'>
<?php foreach ($flow as $flowItem):?>
<div class='flow-item flow-item-<?php echo $idx ++ ?>'><div title='<?php echo $flowItem ?>'><span class='flow-item-display'><?php echo $flowItem ?></span></div></div>
<div class='flow-item flow-item-<?php echo $idx ++ ?>'><div title='<?php echo $flowItem ?>'><div class='flow-item-display'><?php echo $flowItem ?></div></div></div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
<style>
.flow-item {float: left; width: 16.66667%; max-width: 180px; text-align: center; margin-bottom: 9px; padding-right: 15px;}
.flow-item > div {position: relative; padding: 5px 0 5px 8px; line-height: 20px; background: #66A2FF; white-space:nowrap; overflow: visible; color: #3c4353}
.flow-item > div:before, .flow-item > div:after {content: ' '; display: block; width: 0; height: 0; border-style: solid; border-width: 15px 0 15px 10px; border-color: transparent transparent transparent #66A2FF; position: absolute; left: 0; top: 0;}
.flow-chart-row {display: flex; gap: 5px; margin-bottom: 9px;}
.flow-item {background: url('/static/svg/arrow-blue.svg') center no-repeat; background-size: cover; text-align: center; margin: 0; padding-right: 15px; flex:0 1 16%; position: relative; padding: 5px 0 5px 8px; white-space:nowrap; overflow: visible; color: #3c4353; display: flex; align-items: center;}
.flow-item > div {padding-left: 5%;}
.ie-8 .flow-item > div:before {display: none}
.flow-item > div:before {border-left-color: #fff; z-index: 1}
.flow-item > div:after {left: auto; right: -10px; z-index: 2}
.flow-item > div > span {display: flow-root; overflow: hidden;}
.flow-item > div > div {display: flow-root; overflow: hidden; padding-left: 5px;}
.ie-8 .flow-item > div {margin-right: 10px}
.flow-item-0 > div {color: #FFF; font-weight: 400; padding-left: 0;}
.flow-item-0 > div {color: #FFF; font-weight: 400;}
.flow-item-0 > div:before {display: none}
.flow-item-1 > div,
.flow-item-2 > div,
.flow-item-3 > div,
.flow-item-4 > div,
.flow-item-5 > div {background: #E6F0FF}
.flow-item-1 > div:after,
.flow-item-2 > div:after,
.flow-item-3 > div:after,
.flow-item-4 > div:after,
.flow-item-5 > div:after {border-left-color: #E6F0FF}
.flow-item-1,
.flow-item-2,
.flow-item-3,
.flow-item-4,
.flow-item-5 {background-image: url('/static/svg/arrow-white.svg'); }
.block-sm .flow-item {padding-right: 5px}
.block-sm .flow-item > div:before, .block-sm .flow-item > div:after {border-width: 15px 0 15px 6px;}
+26 -7
View File
@@ -580,7 +580,7 @@ class bug extends control
if(empty($moduleOptionMenu)) return print(js::locate(helper::createLink('tree', 'browse', "productID=$productID&view=story")));
/* Get products and projects. */
$products = $this->config->CRProduct ? $this->products : $this->product->getPairs('noclosed', 0, 'program_asc');
$products = $this->config->CRProduct ? $this->products : $this->product->getPairs('noclosed', 0, 'program_asc', 'all');
$projects = array(0 => '');
if($executionID)
{
@@ -1822,11 +1822,6 @@ class bug extends control
if(!isset($users[$assignedTo])) $assignedTo = $this->bug->getModuleOwner($bug->module, $productID);
unset($this->lang->bug->resolutionList['tostory']);
$product = $this->loadModel('product')->getById($productID);
$branch = $product->type == 'branch' ? ($bug->branch > 0 ? $bug->branch . ',0' : '0') : '';
$productBugs = $this->bug->getProductBugPairs($productID, $branch);
unset($productBugs[$bugID]);
$this->bug->checkBugExecutionPriv($bug);
$this->qa->setMenu($this->products, $productID, $bug->branch);
@@ -1834,7 +1829,6 @@ class bug extends control
$this->view->bug = $bug;
$this->view->users = $users;
$this->view->assignedTo = $assignedTo;
$this->view->productBugs = $productBugs;
$this->view->executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0, 'id_desc', $projectID, 'stagefilter');
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'withbranch,noreleased');
$this->view->actions = $this->action->getList('bug', $bugID);
@@ -1961,6 +1955,8 @@ class bug extends control
$actionID = $this->action->create('bug', $bugID, 'Closed', $this->post->comment);
$this->action->logHistory($actionID, $changes);
$this->dao->update(TABLE_BUG)->set('assignedTo')->eq('closed')->where('id')->eq((int)$bugID)->exec();
$this->executeHooks($bugID);
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
@@ -2099,6 +2095,7 @@ class bug extends control
/* Reset $_POST. Do not unset that because the function of close need that in model. */
$_POST = array();
$closedBugs = array();
$bugs = $this->bug->getByList($bugIDList);
foreach($bugs as $bugID => $bug)
{
@@ -2112,7 +2109,11 @@ class bug extends control
$actionID = $this->action->create('bug', $bugID, 'Closed');
$this->action->logHistory($actionID, $changes);
$closedBugs[] = $bugID;
}
$this->dao->update(TABLE_BUG)->set('assignedTo')->eq('closed')->where('id')->in($closedBugs)->exec();
$this->loadModel('score')->create('ajax', 'batchOther');
if(isset($skipBugs)) echo js::alert(sprintf($this->lang->bug->skipClose, join(',', $skipBugs)));
if($viewType)
@@ -2476,6 +2477,24 @@ class bug extends control
return print(html::select('assignedTo', $productMembers, $selectedUser, 'class="form-control"'));
}
/**
* Ajax get product bugs.
*
* @param int $productID
* @param int $bugID
* @access public
* @return string
*/
public function ajaxGetProductBugs($productID, $bugID)
{
$product = $this->loadModel('product')->getById($productID);
$branch = $product->type == 'branch' ? ($bug->branch > 0 ? $bug->branch . ',0' : '0') : '';
$productBugs = $this->bug->getProductBugPairs($productID, $branch);
unset($productBugs[$bugID]);
return print(html::select('duplicateBug', $productBugs, '', "class='form-control' placeholder='{$this->lang->bug->duplicateTip}'"));
}
/**
* Ajax get project team members.
*
+1
View File
@@ -20,6 +20,7 @@
th.c-confirmed {text-align: center;}
.c-severity {overflow: hidden; white-space: nowrap;}
.c-keywords {overflow: hidden; white-space: nowrap;}
.c-id {text-overflow: ellipsis; white-space: nowrap;}
.body-modal #mainMenu>.btn-toolbar {width: auto;}
+10 -4
View File
@@ -24,7 +24,7 @@ if($('#openedBuild').length || $('#resolvedBuild').length || $('[name^=openedBui
{
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
$('#openedBuild, #resolvedBuild, [name^=openedBuilds]').picker({optionRender: markReleasedBuilds});
$('#openedBuild, #resolvedBuild, form [name^=openedBuilds]').picker({optionRender: markReleasedBuilds});
}
/**
@@ -298,7 +298,7 @@ function loadProductModules(productID)
if(typeof(branch) == 'undefined') branch = 0;
if(typeof(moduleID) == 'undefined') moduleID = 0;
if(config.currentMethod == 'edit') moduleID = $('#module').val();
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=bug&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=&currentModuleID=' + moduleID);
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=bug&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=nodeleted&currentModuleID=' + moduleID);
$('#moduleIdBox').load(link, function()
{
$(this).find('select').chosen()
@@ -695,7 +695,7 @@ function loadExecutionBuilds(executionID, num)
else
{
link = createLink('build', 'ajaxGetExecutionBuilds', 'executionID=' + executionID + '&productID=' + productID + '&varName=openedBuild&build=' + oldOpenedBuild + '&branch=' + branch + '&index=0&needCreate=false&type=normal&number=' + num);
$('#openedBuildBox' + num).load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleaseBuilds})});
$('#openedBuildBox' + num).load(link, function(){$(this).find('select').val(oldOpenedBuild).picker({optionRender: markReleasedBuilds})});
oldResolvedBuild = $('#resolvedBuild').val() ? $('#resolvedBuild').val() : 0;
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + '&varName=resolvedBuild&build=' + oldResolvedBuild + '&branch=' + branch);
@@ -866,9 +866,15 @@ function notice()
var html = '';
if($('#execution').length == 0 || $('#execution').val() == 0)
{
var branch = $('#branch').val();
var branch = $('#branch').val();
var projectID = $('#project').val();
if(typeof(branch) == 'undefined') branch = 0;
if(typeof(projectID) == 'undefined') projectID = 0;
var link = createLink('release', 'create', 'productID=' + $('#product').val() + '&branch=' + branch);
if(projectID > 0) link = createLink('projectrelease', 'create', 'projectID=' + projectID);
if(config.onlybody != 'yes') link += link.indexOf('?') >= 0 ? '&onlybody=yes' : '?onlybody=yes';
html += '<a href="' + link + '" data-toggle="modal" data-type="iframe" style="padding-right:5px">' + createRelease + '</a> ';
html += '<a href="javascript:loadProductBuilds(' + $('#product').val() + ')">' + refresh + '</a>';
+12
View File
@@ -2,6 +2,18 @@ function setDuplicate(resolution)
{
if(resolution == 'duplicate')
{
$.ajaxSettings.async = false;
$.get(createLink('bug', 'ajaxGetProductBugs', 'projectID=' + productID + '&bugID=' + bugID),function(data)
{
$('#duplicateBug').replaceWith(data);
$('#pk_duplicateBug-search').parent().parent().remove();
$('#duplicateBug').picker(
{
disableEmptySearch : true,
dropWidth : 'auto'
});
});
$.ajaxSettings.async = true;
$('#duplicateBugBox').show();
}
else
+24 -17
View File
@@ -490,7 +490,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->eq($branch)->fi()
->beginIF(!empty($moduleIdList))->andWhere('module')->in($moduleIdList)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -1023,6 +1023,7 @@ class bugModel extends model
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
->setDefault('assignedDate', $now)
->setDefault('mailto', '')
->stripTags($this->config->bug->editor->assignto['id'], $this->config->allowedTags)
->remove('comment,showModule')
->join('mailto', ',')
@@ -1060,6 +1061,7 @@ class bugModel extends model
->setDefault('lastEditedBy', $this->app->user->account)
->setDefault('lastEditedDate', $now)
->setDefault('assignedDate', $now)
->setDefault('mailto', '')
->stripTags($this->config->bug->editor->confirmbug['id'], $this->config->allowedTags)
->remove('comment')
->join('mailto', ',')
@@ -1182,6 +1184,8 @@ class bugModel extends model
$buildData->builder = $this->app->user->account;
$buildData->createdBy = $this->app->user->account;
$buildData->createdDate = helper::now();
$this->lang->build->name = $this->lang->bug->placeholder->newBuildName;
$this->dao->insert(TABLE_BUILD)->data($buildData)->autoCheck()
->check('name', 'unique', "product = {$buildData->product} AND branch = {$buildData->branch} AND deleted = '0'")
->exec();
@@ -1489,7 +1493,6 @@ class bugModel extends model
$oldBug = $this->getById($bugID);
$bug = fixer::input('post')
->add('id', $bugID)
->add('assignedTo', 'closed')
->add('status', 'closed')
->add('confirmed', 1)
->setDefault('assignedDate', $now)
@@ -2635,7 +2638,7 @@ class bugModel extends model
$bugs = $this->dao->select("t1.*, t2.title as planTitle, IF(t1.`pri` = 0, {$this->config->maxPriValue}, t1.`pri`) as priOrder, IF(t1.`severity` = 0, {$this->config->maxPriValue}, t1.`severity`) as severityOrder")->from(TABLE_BUG)->alias('t1')
->leftJoin(TABLE_PRODUCTPLAN)->alias('t2')->on('t1.plan = t2.id')
->where('t1.product')->in($productIDList)
->andWhere('t1.execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('t1.execution')->in(array_keys($executions))->fi()
->beginIF($branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
->beginIF($modules)->andWhere('t1.module')->in($modules)->fi()
->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi()
@@ -2669,7 +2672,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -2696,7 +2699,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -2723,7 +2726,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -2751,7 +2754,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -2774,7 +2777,7 @@ class bugModel extends model
{
return $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)
->where('product')->in($productIDList)
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->andWhere('confirmed')->eq(0)
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
@@ -2802,7 +2805,7 @@ class bugModel extends model
{
return $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)
->where('product')->in($productIDList)
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
@@ -2832,7 +2835,7 @@ class bugModel extends model
{
return $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)
->where('product')->in($productIDList)
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($status == 'unclosed')->andWhere('status')->ne('closed')->fi()
@@ -2864,7 +2867,7 @@ class bugModel extends model
return $this->dao->select("*, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)
->where('lastEditedDate')->lt($lastEditedDate)
->andWhere('product')->in($productIDList)
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
@@ -2895,7 +2898,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -2923,8 +2926,8 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('t1.branch')->in($branch)->fi()
->beginIF($modules)->andWhere('t1.module')->in($modules)->fi()
->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi()
->beginIF($this->app->tab !== 'qa')->andWhere('t1.execution')->in(array_keys($executions))->fi()
->andWhere('t2.version > t1.storyVersion')
->andWhere('t1.execution')->in(array_keys($executions))
->andWhere('t1.deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('t1.project')->in('0,' . $this->app->user->view->projects)->fi()
->orderBy($orderBy)
@@ -2953,7 +2956,7 @@ class bugModel extends model
->beginIF($branch !== 'all')->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->andWhere('execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('execution')->in(array_keys($executions))->fi()
->andWhere('deleted')->eq(0)
->andWhere('status')->ne('closed')
->andWhere('id')->in($actionIDList)
@@ -3071,7 +3074,7 @@ class bugModel extends model
$bugs = $this->dao->select("t1.*, t2.title as planTitle, IF(`pri` = 0, {$this->config->maxPriValue}, `pri`) as priOrder, IF(`severity` = 0, {$this->config->maxPriValue}, `severity`) as severityOrder")->from(TABLE_BUG)->alias('t1')
->leftJoin(TABLE_PRODUCTPLAN)->alias('t2')->on('t1.plan = t2.id')
->where('t1.product')->in($productIDList)
->andWhere('t1.execution')->in(array_keys($executions))
->beginIF($this->app->tab !== 'qa')->andWhere('t1.execution')->in(array_keys($executions))->fi()
->beginIF($branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
->beginIF($modules)->andWhere('t1.module')->in($modules)->fi()
->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi()
@@ -3366,6 +3369,10 @@ class bugModel extends model
$class .= ' text-ellipsis';
$title = "title='" . $os . "'";
break;
case 'keywords':
$class .= ' text-left';
$title = "title='{$bug->keywords}'";
break;
case 'browser':
$class .= ' text-ellipsis';
$title = "title='" . $browser . "'";
@@ -3594,9 +3601,9 @@ class bugModel extends model
$ccList = substr($ccList, $commaPos + 1);
}
}
elseif(strtolower($toList) == 'closed')
elseif($bug->status == 'closed')
{
$toList = $bug->resolvedBy;
$ccList .= ',' . $bug->resolvedBy;
}
return array($toList, $ccList);
+3 -33
View File
@@ -83,41 +83,14 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
</td>
</tr>
<?php $showExecution = (strpos(",$showFields,", ',execution,') !== false);?>
<tr class='bug-type'>
<th><?php echo $showExecution ? $lang->bug->project : $lang->bug->type;?></th>
<?php if(!$showExecution):?>
<?php $showOS = strpos(",$showFields,", ',os,') !== false;?>
<?php $showBrowser = strpos(",$showFields,", ',browser,') !== false;?>
<td>
<div class='input-group' id='bugTypeInputGroup'>
<?php echo html::select('type', $lang->bug->typeList, $type, "class='form-control'");?>
<?php if($showOS):?>
<div class='table-col'>
<div class='input-group'>
<span class='input-group-addon fix-border'><?php echo $lang->bug->os?></span>
<?php echo html::select('os[]', $lang->bug->osList, $os, "class='form-control chosen' multiple");?>
</div>
</div>
<?php endif;?>
<?php if($showBrowser):?>
<div class='table-col'>
<div class='input-group'>
<span class='input-group-addon fix-border'><?php echo $lang->bug->browser?></span>
<?php echo html::select('browser[]', $lang->bug->browserList, $browser, "class='form-control chosen' multiple");?>
</div>
</div>
<?php endif;?>
</div>
</td>
<?php endif;?>
<?php if($showExecution):?>
<tr>
<th><?php echo $lang->bug->project?></th>
<td>
<div class='table-row'>
<div class='table-col' id='projectBox'>
<?php echo html::select('project', $projects, $projectID, "class='form-control chosen' onchange='loadProductExecutions({$productID}, this.value)'");?>
</div>
<?php $executionClass = ($execution and !$execution->multiple) ? 'hidden' : '';?>
<?php $executionClass = !$showExecution ? 'hidden' : '';?>
<div class="table-col executionBox <?php echo $executionClass;?>">
<div class='input-group' id='executionIdBox'>
<span class='input-group-addon fix-border' id='executionBox'><?php echo $projectModel == 'kanban' ? $lang->bug->kanban : $lang->bug->execution;?></span>
@@ -126,7 +99,6 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
</div>
</div>
</td>
<?php endif;?>
<td>
<div class='input-group' id='buildBox'>
<span class="input-group-addon"><?php echo $lang->bug->openedBuild?></span>
@@ -177,7 +149,6 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
</td>
</tr>
<?php endif;?>
<?php if($showExecution):?>
<?php $showOS = strpos(",$showFields,", ',os,') !== false;?>
<?php $showBrowser = strpos(",$showFields,", ',browser,') !== false;?>
<tr class='bug-type'>
@@ -206,7 +177,6 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
</div>
</td>
</tr>
<?php endif;?>
<?php if(isset($executionType) and $executionType == 'kanban'):?>
<tr>
<th><?php echo $lang->kanbancard->region;?></th>
+2 -1
View File
@@ -16,6 +16,7 @@
<?php
js::set('page', 'resolve');
js::set('productID', $bug->product);
js::set('bugID', $bug->id);
js::set('released', $lang->build->released);
?>
<div id='mainContent' class='main-content'>
@@ -39,7 +40,7 @@ js::set('released', $lang->build->released);
</tr>
<tr id='duplicateBugBox' class='hide'>
<th><?php echo $lang->bug->duplicateBug;?></th>
<td class='required'><?php echo html::select('duplicateBug', $productBugs, '', "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?></td>
<td class='required'><?php echo html::select('duplicateBug', '', '', "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?></td>
</tr>
<tr>
<th><?php echo $lang->bug->resolvedBuild;?></th>
+2
View File
@@ -535,6 +535,7 @@ class commonModel extends model
echo "<a class='dropdown-toggle' data-toggle='dropdown'>";
echo html::avatar($app->user);
echo '</a>';
echo '<script>$("#userDropDownMenu").on("click", function(){$(this).removeClass("dropdown-hover");});$("#userDropDownMenu").on("hover", function(){$(this).next().removeClass("open");$(this).addClass("dropdown-hover");});</script>';
}
}
@@ -2521,6 +2522,7 @@ EOD;
($module == 'file' and strpos('|read|download|uploadimages|ajaxwopifiles|', "|{$method}|") !== false) or
($module == 'report' && $method == 'annualdata') or
($module == 'misc' && $method == 'captcha') or
($module == 'bug' && $method == 'create') or
($module == 'execution' and $method == 'printkanban') or
($module == 'traincourse' and $method == 'ajaxuploadlargefile') or
($module == 'traincourse' and $method == 'playvideo'))
+1 -1
View File
@@ -21,7 +21,7 @@ include 'chosen.html.php';
<div id='userMenu'>
<ul id="userNav" class="nav nav-default">
<li class='dropdown dropdown-hover' id='globalCreate'><?php common::printCreateList();?></li>
<li class='dropdown dropdown-hover has-avatar'><?php common::printUserBar();?></li>
<li class='dropdown dropdown-hover has-avatar' id='userDropDownMenu'><?php common::printUserBar();?></li>
<li class='dropdown dropdown-hover' id='visionSwitcher'><?php common::printVisionSwitcher();?></li>
</ul>
</div>
+2
View File
@@ -251,6 +251,8 @@ class custom extends control
}
$this->custom->deleteItems("lang=$lang&module=$module&section=$field&vision={$this->config->vision}");
if($lang == 'all') $this->custom->deleteItems("lang=$currentLang&module=$module&section=$field&vision={$this->config->vision}");
$data = fixer::input('post')->get();
$emptyKey = false;
foreach($data->keys as $index => $key)
+3
View File
@@ -240,3 +240,6 @@ $config->dev->postParams['testcase']['create']['steps'] = 'string';
$config->dev->postParams['testcase']['create']['expect'] = 'string';
$config->dev->postParams['testcase']['create']['mailto'] = 'string';
$config->dev->postParams['testcase']['create']['keywords'] = 'string';
$config->disableFeature = array();
if(!helper::hasFeature('waterfall')) $config->disableFeature = array('design', 'stage', 'programplan', 'weekly', 'researchplan', 'researchreport', 'gapanalysis');
+5 -4
View File
@@ -9,6 +9,7 @@
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php
if($config->disableFeature and in_array($module, $config->disableFeature)) continue;
$active = ($module == $selectedModule) ? 'active' : '';
$moduleName = zget($lang->dev->tableList, $module, $module);
?>
@@ -36,7 +37,7 @@
<?php foreach($apis as $api):?>
<div class='detail'>
<?php
$methodName = $api['name'];
$methodName = zget($api, 'name', '');
$params = array();
if(isset($api['param']))
{
@@ -46,12 +47,12 @@
?>
<div class='detail-title'>
<?php
echo $api['post'] ? 'GET/POST' : 'GET';
echo '&nbsp;&nbsp;' . $this->createLink($selectedModule, $api['name'], $params, 'json');
echo !empty($api['post']) ? 'GET/POST' : 'GET';
echo '&nbsp;&nbsp;' . $this->createLink($selectedModule, $methodName, $params, 'json');
?>
</div>
<div class='detail-content'>
<?php echo $api['desc'];?>
<?php echo zget($api, 'desc', '');?>
<table class='table table-bordered'>
<tr>
<th><?php echo $lang->dev->params?></th>
+1 -1
View File
@@ -541,7 +541,7 @@ class doc extends control
$this->view->doc = $doc;
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($libID, 'doc', $startModuleID = 0);
$this->view->type = $type;
$this->view->libs = $this->doc->getLibs('all', $extra = 'withObject|noBook', $libID, $objectID);
$this->view->libs = $this->doc->getLibs('all', 'withObject', $libID, $objectID, 'book');
$this->view->lib = $lib;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('noletter|noclosed|nodeleted', $doc->users);
+2 -2
View File
@@ -51,7 +51,7 @@
if($canImportToPracticeLib or $canImportToComponentLib)
{
echo "<div class='btn-group' id='more'>";
echo "<div class='btn-group' id='more' title='{$lang->import}'>";
echo html::a('javascript:;', "<i class='icon icon-diamond'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canImportToPracticeLib) echo '<li>' . html::a('#importToPracticeLib', $lang->doc->importToPracticeLib, '', 'data-toggle="modal"') . '</li>';
@@ -296,7 +296,7 @@
$(function()
{
var simplemde = new SimpleMDE({element: $("#markdownContent")[0],toolbar:false, status: false});
//simplemde.value(String(markdownText));
simplemde.value(String(markdownText));
simplemde.togglePreview();
$('#content .CodeMirror .editor-preview a').attr('target', '_blank');
+1 -1
View File
@@ -249,7 +249,7 @@ js::set('docID', $doc->id);
$(function()
{
var simplemde = new SimpleMDE({element: $("#markdownContent")[0],toolbar:false, status: false});
//simplemde.value(String(markdownText));
simplemde.value(String(markdownText));
simplemde.togglePreview();
$('#content .CodeMirror .editor-preview a').attr('target', '_blank');
+2 -3
View File
@@ -282,7 +282,7 @@ class execution extends control
/* Get tasks and group them. */
if(empty($groupBy))$groupBy = 'story';
if(($groupBy == 'story') and ($execution->type == 'ops'))$groupBy = 'status';
if(($groupBy == 'story') and ($execution->lifetime == 'ops')) $groupBy = 'status';
$sort = common::appendOrder($groupBy);
$tasks = $this->loadModel('task')->getExecutionTasks($executionID, $productID = 0, $status = 'all', $modules = 0, $sort);
$groupBy = str_replace('`', '', $groupBy);
@@ -1531,8 +1531,6 @@ class execution extends control
}
$dateList = date::getDateList($begin, $end, 'Y-m-d', $withWeekend == 'false'? 'noweekend' : '');
//list($cycleTimeAvg, $throughput) = $this->execution->getCFDStatistics($executionID, $dateList, $type);
$chartData = $this->execution->buildCFDData($executionID, $dateList, $type);
if(isset($chartData['line'])) $chartData['line'] = array_reverse($chartData['line']);
@@ -2657,6 +2655,7 @@ class execution extends control
unset($this->lang->kanban->type['story']);
unset($this->lang->kanban->type['bug']);
unset($this->lang->kanban->type['all']);
unset($this->lang->kanban->group->task['story']);
}
if($groupBy == 'story' and $browseType == 'task' and !isset($this->lang->kanban->orderList[$orderBy])) $orderBy = 'id_asc';
+1
View File
@@ -75,3 +75,4 @@
#kanbans .kanban-affixed .kanban-header-col .title.action-dbc .storyColumn .text {color: #fff;}
#kanbans .kanban-affixed .kanban-header-col .title.action-dbc .storyColumn .caret {display: none;}
.kanban-card a[disabled] {color: #313c52;}
.kanban-col .icon-arrow-up + .tooltip {white-space: nowrap;}
+2 -2
View File
@@ -1595,13 +1595,13 @@ $(function()
return false;
});
/* Mofidy dafault color's border color. */
/* Modify color's border color. */
$(document).on('mouseout', '.color0', function()
{
$('.color0 .cardcolor').css('border', '1px solid #b0b0b0');
});
/* Mofidy dafault color's border color. */
/* Modify default color's border color. */
$(document).on('mouseover', '.color0', function()
{
$('.color0 .cardcolor').css('border', '1px solid #fff');
+26
View File
@@ -41,3 +41,29 @@ function adjustTableFooter()
$('.table-footer').css({'left': 0, 'bottom': 0, 'width': 'unset'});
}
}
/**
* Ajax refresh.
*
* @access public
* @return void
*/
function ajaxRefresh()
{
var $table = $('#executionTaskForm').closest('[data-ride="table"]');
if($table.length)
{
var table = $table.data('zui.table');
if(table)
{
table.options.replaceId = 'executionTaskForm';
table.reload();
}
}
$.get(location.href, function(data)
{
var $data = $(data);
$('#mainMenu > div.btn-toolbar.pull-left').html($data.find('#mainMenu > div.btn-toolbar.pull-left').html());
if($data.find('#mainContent .main-col .table-empty-tip').length) $('#mainContent .main-col').html($data.find('#mainContent .main-col'));
});
}
+1 -1
View File
@@ -357,7 +357,7 @@ function renderColumnCount($count, count, col)
}
var text = count + '/' + (col.limit < 0 ? '<i class="icon icon-infinite"></i>' : col.limit);
$count.html(text + '<i class="icon icon-arrow-up"></i>');
$count.html(text + '<i class="icon icon-arrow-up" data-toggle="tooltip" data-original-title="' + kanbanLang.limitExceeded + '"></i>');
if(col.limit != -1 && col.limit < count)
{
+1 -39
View File
@@ -2283,7 +2283,7 @@ class executionModel extends model
$productType = 'normal';
$productNum = count($products);
$productPairs = array(0 => '');
$branches = $this->loadModel('project')->getBranchesByProject($execution->id);
$branches = empty($execution) ? array() : $this->loadModel('project')->getBranchesByProject($execution->id);
foreach($products as $product)
{
@@ -3763,44 +3763,6 @@ class executionModel extends model
return $data;
}
/**
* Get CFD statistics.
*
* @param int $executionID
* @param array $dateList
* @param string $type
* @access public
* @return void
*/
public function getCFDStatistics($executionID, $dateList, $type)
{
$kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $type);
$kanbanData = array_shift($kanbanData);
$cycleTime = array();
foreach($kanbanData->groups as $group)
{
foreach($group->lanes as $lane)
{
if(!isset($lane->items['closed'])) continue;
foreach($lane->items['closed'] as $item)
{
$diffTime = $type == 'story' ? strtotime($item['lastEditedDate']) - strtotime($item['openedDate']) : strtotime($item['closedDate']) - strtotime($item['openedDate']);
$day = round($diffTime / (3600 * 24), 1);
if($day > 0) $cycleTime[$item['id']] = $day;
}
}
}
$itemCount = count($cycleTime);
if(!$itemCount) return array('', '');
$cycleTimeAvg = round(array_sum($cycleTime) / $itemCount, 1);
$throughput = round(($itemCount * 7) / $cycleTimeAvg, 1) . "{$this->lang->execution->kanbanCardsUnit}/" . $this->lang->execution->week;
return array($cycleTimeAvg, $throughput);
}
/**
* Get taskes by search.
*
+2 -2
View File
@@ -47,7 +47,7 @@
<ul class="dropdown-menu">
<?php
$class = common::hasPriv('task', 'export') ? '' : "class=disabled";
$misc = common::hasPriv('task', 'export') ? "class='export'" : "class=disabled";
$misc = common::hasPriv('task', 'export') ? "class='export' data-width=620" : "class=disabled";
$link = common::hasPriv('task', 'export') ? $this->createLink('task', 'export', "execution=$executionID&orderBy=$orderBy&type=$browseType") : '#';
echo "<li $class>" . html::a($link, $lang->story->export, '', $misc) . "</li>";
?>
@@ -103,7 +103,7 @@
<?php foreach($lang->execution->groups as $key => $value):?>
<?php
if(empty($key)) continue;
if($execution->type == 'ops' && $key == 'story') continue;
if($execution->lifetime == 'ops' && $key == 'story') continue;
$active = $key == $groupBy ? "class='active'" : '';
echo "<li $active>"; common::printLink('execution', 'groupTask', "execution=$executionID&groupBy=$key", $value); echo '</li>';
?>
+1 -1
View File
@@ -79,7 +79,7 @@
<?php endif;?>
<?php
if($productID) common::printIcon('story', 'report', "productID=$productID&branchID=&storyType=$storyType&browseType=$type&moduleID=$param&chartType=pie&projectID=$execution->id", '', 'button', 'bar-chart muted');
common::printLink('story', 'export', "productID=$productID&orderBy=id_desc&executionID=$execution->id&browseType=$type&storyType=$storyType", "<i class='icon icon-export muted'></i> " . $lang->story->export, '', "class='btn btn-link export iframe'");
common::printLink('story', 'export', "productID=$productID&orderBy=id_desc&executionID=$execution->id&browseType=$type&storyType=$storyType", "<i class='icon icon-export muted'></i> " . $lang->story->export, '', "class='btn btn-link export iframe' data-width=620");
$canLinkStory = ($execution->hasProduct or $execution->multiple);
if(common::canModify('execution', $execution))
+2 -2
View File
@@ -62,7 +62,7 @@ body {margin-bottom: 25px;}
common::sortFeatureMenu();
foreach(customModel::getFeatureMenu('execution', 'task') as $menuItem)
{
if($execution->type == 'ops' && $menuItem->name == 'needconfirm') continue;
if($execution->lifetime == 'ops' && $menuItem->name == 'needconfirm') continue;
if(isset($menuItem->hidden)) continue;
$menuType = $menuItem->name;
if($menuType == 'QUERY')
@@ -215,7 +215,7 @@ body {margin-bottom: 25px;}
if($useDatatable) include '../../common/view/datatable.html.php';
$customFields = $this->datatable->getSetting('execution');
if($execution->type == 'ops')
if($execution->lifetime == 'ops')
{
foreach($customFields as $id => $customField)
{
+2 -2
View File
@@ -28,7 +28,7 @@
foreach(customModel::getFeatureMenu('execution', 'task') as $menuItem)
{
if($execution->type == 'ops' && $menuItem->name == 'needconfirm') continue;
if($execution->lifetime == 'ops' && $menuItem->name == 'needconfirm') continue;
if(isset($menuItem->hidden)) continue;
$menuType = $menuItem->name;
if(strpos($menuType, 'QUERY') === 0)
@@ -74,7 +74,7 @@
foreach ($lang->execution->groups as $key => $value)
{
if($key == '') continue;
if($execution->type == 'ops' && $key == 'story') continue;
if($execution->lifetime == 'ops' && $key == 'story') continue;
echo '<li' . ($key == $groupBy ? " class='active'" : '') . '>';
common::printLink('execution', 'groupTask', "execution=$executionID&groupBy=$key", $value);
}
+2 -1
View File
@@ -72,7 +72,8 @@
</td>
<?php $params = "testcaseID=$caseID&version=$case->version";?>
<?php if($type == 'assigntome') $params .= "&from=testtask&taskID=$case->task";?>
<td class='c-title text-left' title="<?php echo $case->title?>"><?php echo html::a($this->createLink('testcase', 'view', $params, '', '', $case->project), $case->title, null, "style='color: $case->color' data-app='{$this->app->tab}'");?></td>
<?php $autoIcon = $case->auto == 'auto' ? " <i class='icon icon-draft-edit'></i>" : '';?>
<td class='c-title text-left' title="<?php echo $case->title?>"><?php echo html::a($this->createLink('testcase', 'view', $params, '', '', $case->project), $case->title . $autoIcon, null, "style='color: $case->color' data-app='{$this->app->tab}'");?></td>
<td><span class='label-pri <?php echo 'label-pri-' . $case->pri?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri)?></span></td>
<td><?php echo zget($lang->testcase->typeList, $case->type);?></td>
<td>
+1 -1
View File
@@ -45,7 +45,7 @@
<?php echo !empty($task->desc) ? $task->desc : "<div class='text-center text-muted'>" . $lang->noData . '</div>';?>
</div>
</div>
<?php if($execution->type != 'ops'):?>
<?php if($execution->lifetime != 'ops'):?>
<?php if($task->fromBug != 0):?>
<div class="detail" open>
<div class="detail-title"><?php echo $lang->bug->steps;?></div>
+1 -1
View File
@@ -3,7 +3,7 @@ $maxUploadSize = strtoupper(ini_get('upload_max_filesize'));
js::set('dangerExtensions', ',' . $this->config->file->dangers . ',');
js::set('maxUploadSize', $maxUploadSize);
?>
<div class="file-input-list" data-append-way="before" data-filedName="<?php echo $filesName;?>" data-provide="fileInputList" data-each-file-max-size="<?php echo $maxUploadSize; ?>" data-file-size-error="<?php echo sprintf($lang->file->errorFileSize, $maxUploadSize); ?>">
<div class="file-input-list" data-append-way="before" data-filedName="<?php echo $filesName;?>" name="<?php echo $filesName;?>[]" data-provide="fileInputList" data-each-file-max-size="<?php echo $maxUploadSize; ?>" data-file-size-error="<?php echo sprintf($lang->file->errorFileSize, $maxUploadSize); ?>">
<div class="file-input">
<div class="file-input-edit input-group">
<div class="input-group-cell"><i class="icon icon-paper-clip text-muted"></i></div>
+1 -1
View File
@@ -236,7 +236,7 @@ class gitModel extends model
*/
public function setRepos()
{
$repos = $this->loadModel('repo')->getListBySCM('Git,Gitlab');
$repos = $this->loadModel('repo')->getListBySCM('Git,Gitlab,Gogs,Gitea');
$gitRepos = array();
$paths = array();
foreach($repos as $repo)
+1 -1
View File
@@ -213,7 +213,7 @@ class group extends control
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
if($type == 'byGroup') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload'));
if($type == 'byModule') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'window.parent.location.reload()'));
if($type == 'byModule') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
}
if($type == 'byGroup')
+1 -1
View File
@@ -18,7 +18,7 @@
</h2>
</div>
<form class='table-bymodule pdb-20' method='post' target='hiddenwin'>
<form class='table-bymodule pdb-20 form-ajax' method='post' target='hiddenwin'>
<table class='table table-form'>
<tr class='text-center'>
<td class='strong'><?php echo $lang->group->module;?></td>
+2 -2
View File
@@ -1631,13 +1631,13 @@ $(function()
return false;
});
/* Mofidy dafault color's border color. */
/* Modify default color's border color. */
$(document).on('mouseout', '.color0', function()
{
$('.color0 .cardcolor').css('border', '1px solid #b0b0b0');
});
/* Mofidy dafault color's border color. */
/* Modify default color's border color. */
$(document).on('mouseover', '.color0', function()
{
$('.color0 .cardcolor').css('border', '1px solid #fff');
+2
View File
@@ -103,6 +103,7 @@ $lang->misc->feature->themeDesc = "<p>禅道15系列上线了全新的“
$lang->misc->feature->visionsDesc = "<p>从16.5开始增加了界面概念,用户可以在<span style='color:#0c60e1'>[研发综合界面]</span>中处理研发事务、在<span style='color:#0c60e1'>[运营管理界面]</span>处理日常办公事务。</p><p>在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。</p>";
$lang->misc->feature->visionsImage = 'theme/default/images/main/visions.png';
/* Release Date. */
$lang->misc->releaseDate['18.0'] = '2023-01-03';
$lang->misc->releaseDate['18.0.beta3'] = '2022-12-26';
$lang->misc->releaseDate['18.0.beta2'] = '2022-12-14';
@@ -196,6 +197,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
/* Release Detail. */
$lang->misc->feature->all['18.0'][] = array('title' => '推出自动化测试解决方案;运营管理界面增加工单功能;审批流支持增加所有类型的通知以及挣值计算规则完善。', 'desc' => '');
$lang->misc->feature->all['18.0.beta3'][] = array('title' => '统计模块升级为BI,内置5张宏观管理维度大屏。', 'desc' => '');
$lang->misc->feature->all['18.0.beta2'][] = array('title' => '优化多分支/多平台产品,支持创建孪生需求,计划、版本、发布支持跨分支关联需求和bug,并且禅道客户端实现了机器人会话机制。', 'desc' => '');
+1 -1
View File
@@ -1204,7 +1204,7 @@ EOF;
$this->view->tickets = $tickets;
$this->view->depts = $this->loadModel('dept')->getOptionMenu();
$this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted|noclosed');
$this->view->projects = $this->loadModel('project')->getPairsByProgram(0, 'noclosed');
$this->view->projects = $this->loadModel('project')->getPairsByProgram('', 'noclosed');
$this->view->allProducts = $this->dao->select('*')->from(TABLE_PRODUCT)->where('deleted')->eq('0')->fetchPairs('id', 'name');
$this->view->modulePairs = $this->tree->getModulePairs(0, 'feedback');
$this->view->modules = $this->tree->getOptionMenu(0, $viewType = 'feedback', 0);
+1 -1
View File
@@ -22,7 +22,7 @@
<form method='post' target='hiddenwin'>
<table align='center' class='table table-form w-320px'>
<tr>
<th class='w-120px'><?php echo $lang->my->storyConcept;?></th>
<th class='w-140px'><?php echo $lang->my->storyConcept;?></th>
<td><?php echo html::select('URSR', $URSRList, $URSR, "class='form-control picker URSR'");?></td>
</tr>
<?php if($this->config->systemMode == 'ALM'):?>
+1
View File
@@ -249,6 +249,7 @@ class product extends control
$showBranch = $this->loadModel('branch')->showBranch($productID);
/* Get stories. */
$projectProducts = array();
if($isProjectStory and $storyType == 'story')
{
$showBranch = $this->loadModel('branch')->showBranch($productID, 0, $projectID);
+11 -2
View File
@@ -1169,7 +1169,10 @@ class productModel extends model
if(isset($branchGroup[$productID]))
{
$branchModuleList = $this->tree->getOptionMenu($productID, 'story', 0, array_keys($branchGroup[$productID]));
foreach($branchModuleList as $branchID => $branchModules) $moduleList += $branchModules;
foreach($branchModuleList as $branchID => $branchModules)
{
if(is_array($branchModules)) $moduleList += $branchModules;
}
}
else
{
@@ -2453,7 +2456,13 @@ class productModel extends model
}
elseif($module == 'ticket')
{
return helper::createLink('ticket', 'browse', "browseType=byProduct&productID=%s");
$params = "productID=%s";
if(strpos('browse,view,edit', $method) !== false)
{
$method = 'browse';
$params = "browseType=byProduct&productID=%s";
}
return helper::createLink('ticket', $method, $params);
}
return $link;
+6 -1
View File
@@ -357,7 +357,12 @@ js::set('vision', $this->config->vision);
<?php foreach($stories as $story):?>
<tr data-id='<?php echo $story->id?>' data-estimate='<?php echo $story->estimate?>' <?php if(!empty($story->children)) echo "data-children=" . count($story->children);?> data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
<?php $story->from = $from;?>
<?php if(!empty($branchOptions) and isset($branchOptions[$story->product])) $branchOption = $branchOptions[$story->product];?>
<?php
if(!empty($branchOptions))
{
$branchOption = isset($branchOptions[$story->product]) ? $branchOptions[$story->product] : array();
}
?>
<?php if($this->app->getViewType() == 'xhtml'):?>
<?php
foreach($setting as $key => $value)
+1 -1
View File
@@ -10,7 +10,7 @@ tbody.sortable > tr > td.sort-handler {color: #3c4353 !important;}
.has-prefix {position: relative; display: flex; align-items: center;}
.has-prefix > span {flex: none;}
.has-prefix > a {padding-left: 5px;}
.has-prefix > .icon-cards-view {padding-right: 4px;}
.has-suffix > a {max-width: calc(100% - 100px); padding-right: 5px; color: #0c60e1; display: inline-block;}
+4 -16
View File
@@ -1459,25 +1459,13 @@ class programModel extends model
->fetchAll('project');
}
/* Get the number of project teams. */
$teams = $this->dao->select('t1.root,count(t1.id) as teams')->from(TABLE_TEAM)->alias('t1')
/* Get the members of project teams. */
$teamMembers = $this->dao->select('t1.root,t1.account')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
->where('t1.root')->in($projectKeys)
->andWhere('t1.type')->eq('project')
->andWhere('t2.deleted')->eq(0)
->groupBy('t1.root')
->fetchAll('root');
/* Get the members of project teams. */
if($this->cookie->projectType and $this->cookie->projectType == 'bycard')
{
$teamMembers = $this->dao->select('t1.root,t1.account')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
->where('t1.root')->in($projectKeys)
->andWhere('t1.type')->eq('project')
->andWhere('t2.deleted')->eq(0)
->fetchGroup('root', 'account');
}
->fetchGroup('root', 'account');
/* Process projects. */
foreach($projects as $key => $project)
@@ -1494,7 +1482,7 @@ class programModel extends model
/* Process the hours. */
$project->hours = isset($hours[$project->id]) ? $hours[$project->id] : (object)$emptyHour;
$project->teamCount = isset($teams[$project->id]) ? $teams[$project->id]->teams : 0;
$project->teamCount = isset($teamMembers[$project->id]) ? count($teamMembers[$project->id]) : 0;
$project->leftTasks = isset($leftTasks[$project->id]) ? $leftTasks[$project->id]->tasks : '—';
$project->teamMembers = isset($teamMembers[$project->id]) ? array_keys($teamMembers[$project->id]) : array();
+1
View File
@@ -234,6 +234,7 @@ class programplan extends control
$this->app->loadLang('stage');
$this->view->title = $this->lang->programplan->edit;
$this->view->position[] = $this->lang->programplan->edit;
$this->view->PMUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $plan->PM);
$this->view->parentStage = $this->programplan->getParentStageList($this->session->project, $planID, $plan->product);
$this->view->isCreateTask = $this->programplan->isCreateTask($planID);
$this->view->plan = $plan;
+10 -10
View File
@@ -54,14 +54,14 @@ class programplanModel extends model
{
if(empty($executionID)) return array();
$plans = $this->dao->select('t2.*')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t2.type')->eq('stage')
->beginIF($productID)->andWhere('t1.product')->eq($productID)->fi()
->beginIF($browseType == 'all')->andWhere('t2.project')->eq($executionID)->fi()
->beginIF($browseType == 'parent')->andWhere('t2.parent')->eq($executionID)->fi()
->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
->andWhere('t2.deleted')->eq('0')
$plans = $this->dao->select('t1.*')->from(TABLE_EXECUTION)->alias('t1')
->leftJoin(TABLE_PROJECTPRODUCT)->alias('t2')->on('t1.id = t2.project')
->where('t1.type')->eq('stage')
->beginIF($productID)->andWhere('t2.product')->eq($productID)->fi()
->beginIF($browseType == 'all')->andWhere('t1.project')->eq($executionID)->fi()
->beginIF($browseType == 'parent')->andWhere('t1.parent')->eq($executionID)->fi()
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
->andWhere('t1.deleted')->eq('0')
->orderBy($orderBy)
->fetchAll('id');
@@ -324,14 +324,14 @@ class programplanModel extends model
if($stage['planID'] == $task->execution)
{
$stageIndex[$index]['progress']['totalEstimate'] += $task->estimate;
$stageIndex[$index]['progress']['totalConsumed'] += $task->consumed;
$stageIndex[$index]['progress']['totalConsumed'] += $task->parent == '-1' ? 0 : $task->consumed;
$stageIndex[$index]['progress']['totalReal'] += ($task->left + $task->consumed);
$parent = $stage['parent'];
if(isset($stageIndex[$parent]))
{
$stageIndex[$parent]['progress']['totalEstimate'] += $task->estimate;
$stageIndex[$parent]['progress']['totalConsumed'] += $task->consumed;
$stageIndex[$parent]['progress']['totalConsumed'] += $task->parent == '-1' ? 0 : $task->consumed;
$stageIndex[$parent]['progress']['totalReal'] += ($task->left + $task->consumed);
}
}
+4
View File
@@ -37,6 +37,10 @@
<td class='required' colspan='2'><?php echo html::input('code', $plan->code, "class='form-control'");?></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->programplan->PM;?> </th>
<td colspan='2'><?php echo html::select('PM', $PMUsers, '', "class='form-control picker-select'");?></td>
</tr>
<tr>
<th><?php echo $lang->programplan->percent;?> </th>
<td colspan='2'>
+1 -1
View File
@@ -734,7 +734,7 @@ $(function()
gantt.showDate(new Date());
// Show task in modal on click task
var taskModalTrigger = new $.zui.ModalTrigger({type: 'iframe', width: '80%'});
var taskModalTrigger = new $.zui.ModalTrigger({type: 'iframe', width: '95%'});
gantt.attachEvent('onTaskClick', function(id, e)
{
if($(e.srcElement).hasClass('gantt_close') || $(e.srcElement).hasClass('gantt_open')) return false;
+1 -1
View File
@@ -16,7 +16,7 @@
#budgetUnit {border-left: 0px;}
#projectName {display: inline-block; width: 32%;}
.productsBox a {border-radius: 2px !important;}
.productsBox .required:after {right: -12px !important; top: 10px !important;}
.productsBox .required:after {right: -12px !important; top: 7px !important;}
.productsBox .addProduct {padding-left: 0px !important;}
.productsBox .addProduct.required:after {right: -1px !important;}
.productsBox .input-group-addon > div {display: inline-block !important;}
+11 -1
View File
@@ -16,10 +16,20 @@ $(function()
$('td .execution .label-danger').each(function()
{
$execution = $(this).closest('.execution');
$td = $(this).closest('td');
$td = $(this).closest('td');
if($td.width() < $execution.width())
{
$execution.find('.executionName').css('display', 'inline-block').css('width', $td.width() - $(this).width()).css('overflow', 'hidden').css('float', 'left');
}
})
$('td.c-name .build .icon-code-fork').each(function()
{
$build = $(this).closest('.build');
$td = $(this).closest('td');
if($td.width() < $build.width())
{
$build.find('.buildName').css('display', 'inline-block').css('width', $td.width() - $(this).width()).css('overflow', 'hidden').css('float', 'left');
}
})
})
+7 -4
View File
@@ -827,7 +827,8 @@ class projectModel extends model
->where('type')->eq('project')
->andWhere('deleted')->eq(0)
->andWhere('vision')->eq($this->config->vision)
->beginIF($programID !== '')->andWhere('path')->like("%,$programID,%")->fi()
->beginIF(!empty($programID))->andWhere('path')->like("%,$programID,%")->fi()
->beginIF($programID === 0)->andWhere('parent')->eq(0)->fi()
->beginIF($status != 'all' and $status != 'noclosed')->andWhere('status')->eq($status)->fi()
->beginIF($excludedModel)->andWhere('model')->ne($excludedModel)->fi()
->beginIF($model)->andWhere('model')->eq($model)->fi()
@@ -2273,13 +2274,15 @@ class projectModel extends model
}
break;
case 'name':
$prefix = '';
$suffix = '';
$prefix = '';
$suffix = '';
$projectIcon = '';
if(isset($project->delay)) $suffix = "<span class='label label-danger label-badge'>{$this->lang->project->statusList['delay']}</span>";
$projectType = $project->model == 'scrum' ? 'sprint' : $project->model;
if(!empty($suffix) or !empty($prefix)) echo '<div class="project-name' . (empty($prefix) ? '' : ' has-prefix') . (empty($suffix) ? '' : ' has-suffix') . '">';
if(!empty($prefix)) echo $prefix;
echo html::a($projectLink, "<i class='text-muted icon icon-{$projectType}'></i> " . $project->name, '', "class='text-ellipsis text-primary'");
if($this->config->vision == 'rnd') $projectIcon = "<i class='text-muted icon icon-{$projectType}'></i> ";
echo html::a($projectLink, $projectIcon . $project->name, '', "class='text-ellipsis text-primary'");
if(!empty($suffix)) echo $suffix;
if(!empty($suffix) or !empty($prefix)) echo '</div>';
break;
@@ -112,7 +112,6 @@ $closedCount = 0;
foreach($setting as $value)
{
if($value->id == 'status' and strpos(',all,bysearch,undone,', ",$browseType,") === false) $value->show = false;
if($value->id == 'teamCount' and $browseType == 'all') $value->show = false;
if(commonModel::isTutorialMode() && ($value->id == 'PM' || $value->id == 'budget' || $value->id == 'teamCount')) $value->show = false;
if($value->show) $this->datatable->printHead($value, $orderBy, $vars, $canBatchEdit);
}
+6 -4
View File
@@ -71,10 +71,12 @@
<tr data-id="<?php echo $productID;?>">
<td class="c-id-sm text-muted"><?php echo html::a(helper::createLink($module, 'view', "buildID=$build->id"), sprintf('%03d', $build->id), '', "data-app='project'");?></td>
<td class="c-name" title='<?php echo $build->name;?>'>
<?php echo html::a($this->createLink($module, 'view', "buildID=$build->id"), $build->name, '', "data-app='project'");?>
<?php if(!$build->execution):?>
<span class='icon icon-code-fork text-muted' title='<?php echo $lang->build->integrated;?>'></span>
<?php endif;?>
<span class='build'>
<?php echo html::a($this->createLink($module, 'view', "buildID=$build->id"), $build->name, '', "data-app='project' class='buildName'");?>
<?php if(!$build->execution):?>
<span class='icon icon-code-fork text-muted' title='<?php echo $lang->build->integrated;?>'></span>
<?php endif;?>
</span>
</td>
<?php if($project->hasProduct):?>
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
+2 -2
View File
@@ -155,7 +155,7 @@
<div class='table-row'>
<div class='table-col'>
<?php $hasBranch = $product->type != 'normal' and isset($branchGroups[$product->id]);?>
<div class='input-group <?php if($hasBranch) echo ' has-branch';?>'>
<div class='input-group required <?php if($hasBranch) echo ' has-branch';?>'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?>
</div>
@@ -192,7 +192,7 @@
<div class="col-sm-6">
<div class='table-row'>
<div class='table-col'>
<div class='input-group'>
<div class='input-group required'>
<span class='input-group-addon'><?php echo $lang->product->common;?></span>
<?php echo html::select("products[0]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'");?>
<?php if(common::hasPriv('product', 'create')):?>
+2
View File
@@ -137,6 +137,8 @@ class projectrelease extends control
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $releaseID));
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('view', "releaseID=$releaseID")));
}
+1 -1
View File
@@ -45,7 +45,7 @@
<?php endif;?>
<tr>
<th><?php echo $lang->release->includedBuild;?></th>
<td id='buildBox'><?php echo html::select('build[]', $builds, '', "class='form-control chosen' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td id='buildBox'><?php echo html::select('build[]', $builds, '', "class='form-control picker-select' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td>
<div class="checkbox-primary">
<input type="checkbox" name="sync" value="1" id="sync" checked>
+1 -1
View File
@@ -33,7 +33,7 @@
</tr>
<tr>
<th><?php echo $lang->release->includedBuild;?></th>
<td><?php echo html::select('build[]', $builds, '', "class='form-control chosen' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td><?php echo html::select('build[]', $builds, '', "class='form-control picker-select' multiple data-placeholder='{$lang->build->placeholder->multipleSelect}'");?></td>
<td>
<div class="checkbox-primary">
<input type="checkbox" name="sync" value="1" id="sync" checked>
+21 -1
View File
@@ -1381,9 +1381,29 @@ class repo extends control
{
$content = file($logFile);
$lastLine = $content[count($content) - 1];
if(!strpos($lastLine, 'done'))
{
return print(1);
if(strpos($lastLine, 'empty repository') !== false)
{
@unlink($logFile);
}
elseif(strpos($lastLine, 'Total') !== false)
{
$logContent = file_get_contents($logFile);
if(strpos($logContent, 'Counting objects: 100%') !== false and strpos($logContent, 'Compressing objects: 100%') !== false)
{
@unlink($logFile);
}
else
{
return print(1);
}
}
else
{
return print(1);
}
}
elseif(strpos($lastLine, 'fatal') !== false)
{
+1
View File
@@ -15,6 +15,7 @@
<?php include '../../common/view/tablesorter.html.php';?>
<style>
#queryBox {padding-top: 25px;}
#queryBox.show {min-height: 66px;}
.search-form #bug-search .form-actions {width: 115px !important;}
</style>
<div class='main-content' id='mainContent'>
+1
View File
@@ -15,6 +15,7 @@
<?php include '../../common/view/tablesorter.html.php';?>
<style>
.search-form #story-search .form-actions {width: 115px !important;}
#queryBox.show {min-height: 66px;}
</style>
<div class='main-content' id='mainContent'>
<div class='main-header'>
+1
View File
@@ -15,6 +15,7 @@
<?php include '../../common/view/tablesorter.html.php';?>
<style>
#queryBox {padding-top: 25px;}
#queryBox.show {min-height: 66px;}
.search-form #task-search .form-actions {width: 115px !important;}
</style>
<div class='main-content' id='mainContent'>
+3 -1
View File
@@ -37,8 +37,10 @@ class screen extends control
* @access public
* @return void
*/
public function view($screenID, $year = 2022, $dept = 0, $account = '')
public function view($screenID, $year = 0, $dept = 0, $account = '')
{
if(empty($year)) $year = date('Y');
if($screenID == 3) $this->locate($this->createLink('report', 'annualData'));
$screen = $this->screen->getByID($screenID, $year, $dept, $account);
+4 -10
View File
@@ -675,13 +675,10 @@ class searchModel extends model
$typeCount = $this->dao->select("objectType, count(*) as objectCount")
->from(TABLE_SEARCHINDEX)
->where('((vision')->eq($this->config->vision)
->beginIF(!empty($allowedObject))->andWhere('objectType')->in($allowedObject)->fi()
->andWhere('objectType')->in($allowedObject)
->markRight(1)
->beginIF(!empty($filterObject))
->orWhere('(objectType')->in($filterObject)
->markRight(1)
->fi()
->markRight(1)
->markRight(2)
->andWhere('addedDate')->le(helper::now())
->groupBy('objectType')
->fetchPairs('objectType', 'objectCount');
@@ -717,13 +714,10 @@ class searchModel extends model
->from(TABLE_SEARCHINDEX)
->where("(MATCH(title,content) AGAINST('{$againstCond}' IN BOOLEAN MODE) >= 1 {$likeCondition})")
->andWhere('((vision')->eq($this->config->vision)
->beginIF(!empty($allowedObject))->andWhere('objectType')->in($allowedObject)->fi()
->andWhere('objectType')->in($allowedObject)
->markRight(1)
->beginIF(!empty($filterObject))
->orWhere('(objectType')->in($filterObject)
->markRight(1)
->fi()
->markRight(1)
->markRight(2)
->andWhere('addedDate')->le(helper::now())
->orderBy('score_desc, editedDate_desc')
->query();
+32 -4
View File
@@ -142,24 +142,52 @@ class stage extends control
public function setType($lang2Set = '')
{
$this->loadModel('custom');
$lang = $this->app->getClientLang();
if(empty($lang2Set)) $lang2Set = $this->app->getClientLang();
$currentLang = $this->app->getClientLang();
$fieldList = zget($this->lang->stage, 'typeList', '');
if($lang2Set == 'all')
{
$fieldList = array();
$items = $this->custom->getItems("lang=all&module=stage&section=typeList&vision={$this->config->vision}");
foreach($items as $key => $item) $fieldList[$key] = $item->value;
}
/* Check whether the current language has been customized. */
$dbFields = $this->custom->getItems("lang=$lang2Set&module=stage&section=typeList&vision={$this->config->vision}");
if(empty($dbFields)) $dbFields = $this->custom->getItems("lang=" . ($lang2Set == $currentLang ? 'all' : $currentLang) . "&module=stage&section=typeList");
if($dbFields)
{
$dbField = reset($dbFields);
if($lang2Set != $dbField->lang)
{
$lang2Set = $dbField->lang;
foreach($fieldList as $key => $value)
{
if(isset($dbFields[$key]) and $value != $dbFields[$key]->value) $fieldList[$key] = $dbFields[$key]->value;
}
}
}
if($_POST)
{
$data = fixer::input('post')->get();
$this->custom->deleteItems("lang={$data->lang}&module=stage&section=typeList");
if($data->lang == 'all') $this->custom->deleteItems("lang=$currentLang&module=stage&section=typeList");
foreach($data->keys as $index => $key)
{
$value = $data->values[$index];
if(!$value or !$key) continue;
$this->custom->setItem("all.stage.typeList.{$key}", $value);
$this->custom->setItem("{$data->lang}.stage.typeList.{$key}", $value);
}
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('stage', 'settype', "lang2Set=$data->lang")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('stage', 'settype', "lang2Set=" . ($data->lang == 'all' ? 'all' : ''))));
}
$this->view->title = $this->lang->stage->common . $this->lang->colon . $this->lang->stage->setType;
$this->view->currentLang = $lang;
$this->view->currentLang = $currentLang;
$this->view->lang2Set = !empty($lang2Set) ? $lang2Set : $lang;
$this->view->fieldList = $fieldList;
$this->display();
}
+1 -1
View File
@@ -50,7 +50,7 @@ EOT;
</tr>
</thead>
<tbody>
<?php foreach($lang->stage->typeList as $key => $value):?>
<?php foreach($fieldList as $key => $value):?>
<tr class='text-center'>
<td class='w-70px'>
<?php echo $key;?>
+2 -2
View File
@@ -55,7 +55,7 @@ $config->story->excludeCheckFileds = ',uploadImage,category,reviewer,reviewDitto
global $lang, $app;
$config->story->datatable = new stdclass();
$config->story->datatable->defaultField = array('id', 'title', 'pri', 'plan', 'status', 'openedBy', 'estimate', 'reviewedBy', 'stage', 'assignedTo', 'taskCount', 'actions');
$config->story->datatable->defaultField = array('id', 'title', 'pri', 'plan', 'status', 'estimate', 'reviewedBy', 'stage', 'assignedTo', 'actions');
$config->story->datatable->fieldList['id']['title'] = 'idAB';
$config->story->datatable->fieldList['id']['fixed'] = 'left';
@@ -79,7 +79,7 @@ $config->story->datatable->fieldList['title']['required'] = 'yes';
$config->story->datatable->fieldList['pri']['title'] = 'priAB';
$config->story->datatable->fieldList['pri']['fixed'] = 'left';
$config->story->datatable->fieldList['pri']['width'] = '50';
$config->story->datatable->fieldList['pri']['width'] = '40';
$config->story->datatable->fieldList['pri']['required'] = 'no';
$config->story->datatable->fieldList['pri']['name'] = $this->lang->story->pri;
+15 -3
View File
@@ -73,7 +73,11 @@ class story extends control
if(empty($objectID)) $objectID = $this->session->project;
$projectID = $objectID;
if(!$this->session->multiple) $projectID = $this->session->project;
if(!$this->session->multiple)
{
$projectID = $this->session->project;
$objectID = $this->execution->getNoMultipleID($projectID);
}
$projectID = isset($objects[$projectID]) ? $projectID : $this->session->project;
$projectID = $this->project->saveState($projectID, $objects);
$this->project->setMenu($projectID);
@@ -270,7 +274,7 @@ class story extends control
else
{
$sessionStoryList = $this->session->storyList;
if(count($_POST['branches']) > 1) $sessionStoryList = preg_replace('/branch=(\d+|[A-Za-z]+)/', 'branch=all', $this->session->storyList);
if(!empty($_POST['branches']) and count($_POST['branches']) > 1) $sessionStoryList = preg_replace('/branch=(\d+|[A-Za-z]+)/', 'branch=all', $this->session->storyList);
$response['locate'] = $sessionStoryList;
}
}
@@ -341,6 +345,7 @@ class story extends control
$verify = htmlSpecialString($story->verify);
$keywords = $story->keywords;
$mailto = $story->mailto;
$category = $story->category;
}
if($bugID > 0)
@@ -475,6 +480,7 @@ class story extends control
$this->view->URS = $storyType == 'story' ? $this->story->getProductStoryPairs($productID, $branch, $moduleIdList, 'changing,active,reviewing', 'id_desc', 0, '', 'requirement') : '';
$this->view->needReview = ($this->app->user->account == $product->PO or $objectID > 0 or $this->config->story->needReview == 0 or !$this->story->checkForceReview()) ? "checked='checked'" : "";
$this->view->type = $storyType;
$this->view->category = !empty($category) ? $category : 'feature';
$this->display();
}
@@ -1052,6 +1058,7 @@ class story extends control
unset($stories[$id]);
}
if(!empty($twins)) echo js::alert(sprintf($this->lang->story->batchEditTip, $twins));
if(empty($stories)) return print(js::locate($this->session->storyList));
$this->loadModel('branch');
if($productID and !$executionID)
@@ -1821,6 +1828,8 @@ class story extends control
$this->action->logHistory($actionID, $changes);
}
$this->dao->update(TABLE_STORY)->set('assignedTo')->eq('closed')->where('id')->eq((int)$storyID)->exec();
$this->executeHooks($storyID);
if(isonlybody())
@@ -1967,6 +1976,8 @@ class story extends control
if(!empty($stories[$storyID]->twins)) $this->story->syncTwins($storyID, $stories[$storyID]->twins, $changes, 'Closed');
}
$this->dao->update(TABLE_STORY)->set('assignedTo')->eq('closed')->where('id')->in(array_keys($allChanges))->exec();
}
if(!dao::isError()) $this->loadModel('score')->create('ajax', 'batchOther');
@@ -2277,7 +2288,7 @@ class story extends control
}
else
{
return print(js::closeModal('parent.parent', 'this', 'function(){parent.parent.$(\'[data-ride="searchList"]\').searchList();}'));
return print(js::reload('parent.parent'));
}
}
return print(js::locate($this->createLink('story', 'view', "storyID=$storyID&version=0&param=0&storyType=$storyType"), 'parent'));
@@ -2457,6 +2468,7 @@ class story extends control
$this->view->type = $type;
$this->view->stories2Link = $stories2Link;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->storyType = $storyType;
$this->display();
}
+1 -1
View File
@@ -31,7 +31,7 @@ function loadBranches(product, branch, storyID)
if(!branch) branch = 0;
var currentModuleID = $('#modules' + storyID).val();
moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + product + '&viewtype=story&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=' + storyID + '&needManage=false&extra=&currentModuleID=' + currentModuleID);
moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + product + '&viewtype=story&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=' + storyID + '&needManage=false&extra=nodeleted&currentModuleID=' + currentModuleID);
$('#modules' + storyID).parent('td').load(moduleLink, function(){$('#modules' + storyID).chosen();});
planID = $('#plans' + storyID).val();
+1 -1
View File
@@ -293,7 +293,7 @@ function loadModuleForTwins(productID, branch, branchIndex)
{
/* Load module */
var currentModule = 0;
var moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=' + branchIndex + '&needManage=false&extra=&currentModuleID=' + currentModule);
var moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=' + branchIndex + '&needManage=false&extra=nodeleted&currentModuleID=' + currentModule);
if(branchIndex > 0)
{
var $moduleIDBox = $('.addBranchesBox'+ branchIndex +' #moduleIdBox');
+8 -8
View File
@@ -449,7 +449,7 @@ $lang->story->chosen->reviewedBy = '选择评审人...';
$lang->story->notice = new stdClass();
$lang->story->notice->closed = "您选择的{$lang->SRCommon}已经被关闭了!";
$lang->story->notice->reviewerNotEmpty = '该需求需要评审,评审人员不能为空。';
$lang->story->notice->reviewerNotEmpty = "该{$lang->SRCommon}需要评审,评审人员不能为空。";
$lang->story->notice->changePlan = '所属计划只能改为一条,修改后才能保存成功。';
$lang->story->convertToTask = new stdClass();
@@ -468,20 +468,20 @@ $lang->story->categoryList['experience'] = '体验';
$lang->story->categoryList['improve'] = '改进';
$lang->story->categoryList['other'] = '其他';
$lang->story->changeTip = '只有激活状态的需求,才能进行变更';
$lang->story->changeTip = "只有激活状态的{$lang->SRCommon},才能进行变更";
$lang->story->reviewTip = array();
$lang->story->reviewTip['active'] = '该需求已是激活状态,无需评审';
$lang->story->reviewTip['notReviewer'] = '您不是该需求的评审人员,无法进行评审操作';
$lang->story->reviewTip['active'] = "该{$lang->SRCommon}已是激活状态,无需评审";
$lang->story->reviewTip['notReviewer'] = "您不是该{$lang->SRCommon}的评审人员,无法进行评审操作";
$lang->story->reviewTip['reviewed'] = '您已评审';
$lang->story->recallTip = array();
$lang->story->recallTip['actived'] = '该需求未发起评审流程,无需撤销操作';
$lang->story->recallTip['actived'] = "该{$lang->SRCommon}未发起评审流程,无需撤销操作";
$lang->story->subDivideTip = array();
$lang->story->subDivideTip['subStory'] = '子需求无法细分';
$lang->story->subDivideTip['notWait'] = '该需求%s,无法进行细分操作';
$lang->story->subDivideTip['notActive'] = '需求不是激活状态,无法进行细分操作';
$lang->story->subDivideTip['subStory'] = "子{$lang->SRCommon}无法细分";
$lang->story->subDivideTip['notWait'] = "该{$lang->SRCommon}%s,无法进行细分操作";
$lang->story->subDivideTip['notActive'] = "{$lang->SRCommon}不是激活状态,无法进行细分操作";
$lang->story->subDivideTip['twinsSplit'] = '孪生需求不可细分';
$lang->story->featureBar['browse']['all'] = '全部';
+12 -9
View File
@@ -352,7 +352,7 @@ class storyModel extends model
if($executionID != 0)
{
$this->linkStory($executionID, $this->post->product, $storyID);
if($this->config->systemMode == 'new' and $executionID != $this->session->project) $this->linkStory($this->session->project, $this->post->product, $storyID);
if($this->config->systemMode == 'ALM' and $executionID != $this->session->project) $this->linkStory($this->session->project, $this->post->product, $storyID);
$this->loadModel('kanban');
@@ -906,11 +906,14 @@ class storyModel extends model
return false;
}
$storyPlan = !empty($_POST['plan']) ? array_filter($_POST['plan']) : array();
$storyPlan = array();
if(!empty($_POST['plan'])) $storyPlan = is_array($_POST['plan']) ? array_filter($_POST['plan']) : array($_POST['plan']);
if(count($storyPlan) > 1)
{
$oldStoryPlan = !empty($oldStory->planTitle) ? array_keys($oldStory->planTitle) : array();
if(!empty(array_diff($storyPlan,$oldStoryPlan)) or !empty(array_diff($oldStoryPlan,$storyPlan)))
$oldStoryPlan = !empty($oldStory->planTitle) ? array_keys($oldStory->planTitle) : array();
$oldPlanDiff = array_diff($storyPlan, $oldStoryPlan);
$storyPlanDiff = array_diff($oldStoryPlan, $storyPlan);
if(!empty($oldPlanDiff) or !empty($storyPlanDiff))
{
dao::$errors[] = $this->lang->story->notice->changePlan;
return false;
@@ -1986,7 +1989,6 @@ class storyModel extends model
$now = helper::now();
$story = fixer::input('post')
->add('id', $storyID)
->add('assignedTo', 'closed')
->add('status', 'closed')
->add('stage', 'closed')
->setDefault('lastEditedBy', $this->app->user->account)
@@ -2077,7 +2079,6 @@ class storyModel extends model
$story->lastEditedDate = $now;
$story->closedBy = $this->app->user->account;
$story->closedDate = $now;
$story->assignedTo = 'closed';
$story->assignedDate = $now;
$story->status = 'closed';
$story->stage = 'closed';
@@ -4447,9 +4448,9 @@ class storyModel extends model
$ccList = substr($ccList, $commaPos + 1);
}
}
elseif($toList == 'closed')
elseif($story->status == 'closed')
{
$toList = $story->openedBy;
$ccList .= ',' . $story->openedBy;
}
return array($toList, $ccList);
@@ -6437,8 +6438,10 @@ class storyModel extends model
*/
public function getStoriesReviewer($productID = 0)
{
$this->loadModel('user');
$product = $this->loadModel('product')->getByID($productID);
$reviewers = $this->loadModel('user')->getProductViewListUsers($product, '', '', '', '');
$reviewers = $product->reviewer;
if(!$reviewers and $product->acl != 'open') $reviewers = $this->user->getProductViewListUsers($product, '', '', '', '');
return $this->user->getPairs('noclosed|nodeleted', '', 0, $reviewers);
}
+1 -1
View File
@@ -265,7 +265,7 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
<div class="table-col categoryBox">
<div class="input-group">
<span class="input-group-addon fix-border br-0"><?php echo $lang->story->category;?></span>
<?php echo html::select('category', $lang->story->categoryList, 'feature', "class='form-control chosen'");?>
<?php echo html::select('category', $lang->story->categoryList, $category, "class='form-control chosen'");?>
</div>
</div>
<div class="table-col <?php echo $hiddenPri?> priBox">
+1 -1
View File
@@ -191,7 +191,7 @@ function loadProductModules(productID, branch)
currentModule = $('#module').val();
}
var moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=&currentModuleID=' + currentModule);
var moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=story&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=nodeleted&currentModuleID=' + currentModule);
var $moduleIDBox = $('#moduleIdBox');
$moduleIDBox.load(moduleLink, function()
{
+8
View File
@@ -24,6 +24,13 @@
</h2>
</div>
<div id='queryBox' data-module='story' class='show divider'></div>
<?php if(empty($stories2Link)):?>
<div class='table-empty-tip'>
<p>
<span class='text-muted'><?php echo $storyType == 'story' ? $lang->story->noRequirement : $lang->story->noStory;?></span>
</p>
</div>
<?php else:?>
<form method='post' target='hiddenwin' id='linkStoryForm' class='main-table table-story'>
<?php if($stories2Link):?>
<table class='table tablesorter table-bordered' id='storyList'>
@@ -83,6 +90,7 @@
</div>
<?php endif;?>
</form>
<?php endif;?>
</div>
<script>
$(function()
@@ -24,15 +24,15 @@
</tr>
</thead>
<tbody>
<tr>
<?php foreach($changedStories as $story):?>
<td><?php echo $story->id;?></td>
<td><?php echo $story->title;?></td>
<td style='color: red'><?php echo $lang->story->changed;?></td>
<td><?php echo $story->version;?></td>
<td><?php echo zget($users, $story->openedBy);?></td>
<?php endforeach;?>
</tr>
<?php foreach($changedStories as $story):?>
<tr>
<td><?php echo $story->id;?></td>
<td><?php echo $story->title;?></td>
<td style='color: red'><?php echo $lang->story->changed;?></td>
<td><?php echo $story->version;?></td>
<td><?php echo zget($users, $story->openedBy);?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class="alert alert-info mg-0">
+1 -1
View File
@@ -198,7 +198,7 @@ $config->task->datatable->fieldList['story']['width'] = '80';
$config->task->datatable->fieldList['story']['required'] = 'no';
$config->task->datatable->fieldList['story']['name'] = $lang->task->story;
$config->task->datatable->fieldList['story']['control'] = 'select';
$config->task->datatable->fieldList['story']['dataSource'] = array('module' => 'story', 'method' => 'getExecutionStories', 'params' => '$executionID', 'pairs' => array('id', 'title'));
$config->task->datatable->fieldList['story']['dataSource'] = array('module' => 'story', 'method' => 'getExecutionStoryPairs', 'params' => '$executionID&0&all&&&active');
$config->task->datatable->fieldList['mailto']['title'] = 'mailto';
$config->task->datatable->fieldList['mailto']['fixed'] = 'no';
+1 -7
View File
@@ -471,9 +471,6 @@ class task extends control
$modules = $this->loadModel('tree')->getTaskOptionMenu($executionID, 0, 0, $showAllModule ? 'allModule' : '');
/* Set Custom*/
$project = $this->project->getByID($execution->project);
if($project->model == 'waterfall') $this->config->task->create->requiredFields .= ',estStarted,deadline';
foreach(explode(',', $this->config->task->customBatchCreateFields) as $field)
{
if($execution->type == 'stage' and strpos('estStarted,deadline', $field) !== false) continue;
@@ -780,9 +777,6 @@ class task extends control
/* Set Custom*/
if(isset($execution))
{
$project = $this->project->getByID($execution->project);
if($project->model == 'waterfall') $this->config->task->edit->requiredFields .= ',estStarted,deadline';
foreach(explode(',', $this->config->task->customBatchEditFields) as $field)
{
if($execution->type == 'stage' and strpos('estStarted,deadline', $field) !== false) continue;
@@ -2118,7 +2112,7 @@ class task extends control
{
$execution = $this->execution->getById($executionID);
$allExportFields = $this->config->task->exportFields;
if($execution->type == 'ops') $allExportFields = str_replace(' story,', '', $allExportFields);
if($execution->lifetime == 'ops') $allExportFields = str_replace(' story,', '', $allExportFields);
if($_POST)
{
+21 -4
View File
@@ -579,7 +579,11 @@ class taskModel extends model
if(!$taskID) return true;
$tasks = $this->dao->select('`id`,`estimate`,`consumed`,`left`, status')->from(TABLE_TASK)->where('parent')->eq($taskID)->andWhere('status')->ne('cancel')->andWhere('deleted')->eq(0)->fetchAll('id');
if(empty($tasks)) return true;
if(empty($tasks))
{
$this->dao->update(TABLE_TASK)->set('consumed')->eq(0)->where('id')->eq($taskID)->exec();
return true;
}
$estimate = 0;
$consumed = 0;
@@ -1479,9 +1483,6 @@ class taskModel extends model
return false;
}
$project = $this->loadModel('project')->getByID($oldTask->project);
if($project->model == 'waterfall') $this->config->task->edit->requiredFields .= ',estStarted,deadline';
foreach(explode(',', $this->config->task->edit->requiredFields) as $field)
{
$field = trim($field);
@@ -2855,6 +2856,22 @@ class taskModel extends model
->fetchAll();
}
/**
* Get taskList date record.
*
* @param int|array $taskID
* @access public
* @return array
*/
public function getTaskDateRecord($taskID)
{
return $this->dao->select('id,date')->from(TABLE_EFFORT)->where('objectID')->in($taskID)
->andWhere('objectType')->eq('task')
->andWhere('deleted')->eq('0')
->orderBy('date')
->fetchAll('id');
}
/**
* Get estimate by id.
*
+1 -1
View File
@@ -127,7 +127,7 @@ foreach(explode(',', $config->task->create->requiredFields) as $field)
</div>
</td>
</tr>
<?php if($execution->type != 'ops'):?>
<?php if($execution->lifetime != 'ops'):?>
<tr id='testStoryBox' class='hidden'>
<th><?php echo $lang->task->selectTestStory;?></th>
<td colspan='3'>
+1 -1
View File
@@ -118,7 +118,7 @@ foreach(explode(',', $config->task->edit->requiredFields) as $field)
</div>
</td>
</tr>
<?php if($execution->type != 'ops'):?>
<?php if($execution->lifetime != 'ops'):?>
<tr>
<th><?php echo $lang->task->story;?></th>
<td><span id="storyIdBox"><?php echo html::select('story', $stories, $task->story, "class='form-control chosen' data-drop_direction='down' data-max_drop_width='0'");?></span></td>
+2 -2
View File
@@ -60,7 +60,7 @@
<?php echo !empty($task->desc) ? $task->desc : "<div class='text-center text-muted'>" . $lang->noData . '</div>';?>
</div>
</div>
<?php if($execution->type != 'ops'):?>
<?php if($execution->lifetime != 'ops'):?>
<?php if($task->fromBug != 0):?>
<div class="detail">
<div class="detail-title"><?php echo $lang->bug->steps;?></div>
@@ -227,7 +227,7 @@
?>
<td title='<?php echo $moduleTitle?>'><?php echo $printModule?></td>
</tr>
<?php if($execution->type != 'ops'):?>
<?php if($execution->lifetime != 'ops'):?>
<tr class='nofixed'>
<th><?php echo $lang->task->story;?></th>
<td>
+9 -2
View File
@@ -548,7 +548,7 @@ class testcase extends control
$modules = $this->tree->getAllChildID($modules);
}
$stories = $this->story->getProductStoryPairs($productID, $branch, $modules, 'active', 'id_desc', 50, 'null', 'story', false);
$stories = $this->story->getProductStoryPairs($productID, $branch, $modules, 'active', 'id_desc', 50, 'full', 'story', false);
if($this->app->tab != 'qa' and $this->app->tab != 'product')
{
$projectID = $this->app->tab == 'project' ? $this->session->project : $this->session->execution;
@@ -998,7 +998,14 @@ class testcase extends control
if($case->module) $moduleIdList = $this->tree->getAllChildID($case->module);
$moduleIdList = (!in_array($this->app->tab, array('execution', 'project')) and empty($stories)) ? 0 : $moduleIdList;
$stories = $this->story->getProductStoryPairs($productID, $case->branch, $moduleIdList, 'all','id_desc', 0, 'full', 'story', false);
if($this->app->tab == 'execution')
{
$stories = $this->story->getExecutionStoryPairs($case->execution, $productID, $case->branch, $moduleIdList);
}
else
{
$stories = $this->story->getProductStoryPairs($productID, $case->branch, $moduleIdList, 'all','id_desc', 0, 'full', 'story', false);
}
$this->view->productID = $productID;
$this->view->product = $product;
+1 -1
View File
@@ -6,7 +6,7 @@ body {margin-bottom: 25px;}
#caseForm table tbody tr td {overflow: hidden; white-space: nowrap;}
#caseForm .setting {height: 25px;}
#caseForm table tbody .c-name {overflow: hidden; padding-right: 65px;}
#caseForm table tbody .c-name a:first-child {overflow: hidden; display: inline-block; width: 100%;}
#caseForm table tbody .c-name a:first-child {overflow: hidden; display: inline-block; max-width: 100%;}
.dropdown-menu.with-search {padding: 0; min-width: 150px; overflow: hidden; max-height: 302px;}
.dropdown-menu > .menu-search .input-group {width: 100%;}
+1 -1
View File
@@ -67,7 +67,7 @@ function loadBranches(product, branch, caseID, oldBranch)
if(result)
{
var currentModuleID = $('#modules' + caseID).val();
moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + product + '&viewtype=case&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=' + caseID + '&needManage=false&extra=&currentModuleID=' + currentModuleID);
moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + product + '&viewtype=case&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=' + caseID + '&needManage=false&extra=nodeleted&currentModuleID=' + currentModuleID);
$('#modules' + caseID).parent('td').load(moduleLink, function()
{
$("#modules" + caseID).attr('onchange', "loadStories("+ product + ", this.value, " + caseID + ")").chosen();
+1 -1
View File
@@ -89,7 +89,7 @@ function loadProductModules(productID, branch)
if(typeof(branch) == 'undefined') branch = $('#branch').val();
if(!branch) branch = 0;
var currentModuleID = config.currentMethod == 'edit' ? $('#module').val() : 0;
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=case&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=&currentModuleID=' + currentModuleID);
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=case&branch=' + branch + '&rootModuleID=0&returnType=html&fieldID=&needManage=true&extra=nodeleted&currentModuleID=' + currentModuleID);
$('#moduleIdBox').load(link, function()
{
var $inputGroup = $(this);

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