diff --git a/Makefile b/Makefile index 0c1f450754..00a9eb74ce 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,7 @@ zentaoxx: sed -i "s/'..\/..\/common\/view\/footer.html.php'/\$$app->getModuleRoot() . 'common\/view\/footer.html.php'/g" zentaoxx/extension/xuan/conference/view/admin.html.php echo "ALTER TABLE \`zt_user\` ADD \`pinyin\` varchar(255) NOT NULL DEFAULT '' AFTER \`realname\`;" >> zentaoxx/db/xuanxuan.sql mkdir zentaoxx/tools; cp tools/cn2tw.php zentaoxx/tools; cd zentaoxx/tools; php cn2tw.php - cp tools/en2de.php zentaoxx/tools; cd zentaoxx/tools; php en2de.php ../ + cp tools/en2other.php zentaoxx/tools; cd zentaoxx/tools; php en2other.php ../ rm -rf zentaoxx/tools #zip -rqm -9 zentaoxx.$(VERSION).zip zentaoxx/* #rm -rf xuan.zip xuan zentaoxx diff --git a/db/standard/zentao17.2.sql b/db/standard/zentao17.2.sql index 1b2405df2f..6fdf543367 100644 --- a/db/standard/zentao17.2.sql +++ b/db/standard/zentao17.2.sql @@ -30,7 +30,7 @@ CREATE TABLE `zt_acl` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `zt_action` ( - `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `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, @@ -1009,7 +1009,7 @@ CREATE TABLE `zt_grouppriv` ( UNIQUE KEY `group` (`group`,`module`,`method`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `zt_history` ( - `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `id` int(9) unsigned NOT NULL AUTO_INCREMENT, `action` mediumint(8) unsigned NOT NULL DEFAULT '0', `field` varchar(30) NOT NULL DEFAULT '', `old` text NOT NULL, @@ -1091,6 +1091,7 @@ CREATE TABLE `zt_im_chat` ( `editedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `lastActiveTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `lastMessage` int(11) unsigned NOT NULL DEFAULT '0', + `lastMessageIndex` int(11) unsigned NOT NULL DEFAULT 0, `dismissDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `pinnedMessages` text NOT NULL, PRIMARY KEY (`id`), @@ -1107,6 +1108,8 @@ CREATE TABLE `zt_im_chat_message_index` ( `tableName` char(64) NOT NULL, `start` int(11) unsigned NOT NULL, `end` int(11) unsigned NOT NULL, + `startIndex` int(11) unsigned NOT NULL, + `endIndex` int(11) unsigned NOT NULL, `startDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `endDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `count` mediumint(8) unsigned NOT NULL, @@ -1115,7 +1118,9 @@ CREATE TABLE `zt_im_chat_message_index` ( KEY `start` (`start`), KEY `end` (`end`), KEY `startDate` (`startDate`), - KEY `endDate` (`endDate`) + KEY `endDate` (`endDate`), + KEY `chatstartindex` (`gid`,`startIndex`), + KEY `chatendindex` (`gid`,`endIndex`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `zt_im_chatuser` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, @@ -1130,6 +1135,7 @@ CREATE TABLE `zt_im_chatuser` ( `quit` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `category` varchar(40) NOT NULL DEFAULT '', `lastReadMessage` int(11) unsigned NOT NULL DEFAULT '0', + `lastReadMessageIndex` int(11) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `chatuser` (`cgid`,`user`), KEY `cgid` (`cgid`), @@ -1179,6 +1185,7 @@ CREATE TABLE `zt_im_message` ( `cgid` char(40) NOT NULL DEFAULT '', `user` varchar(30) NOT NULL DEFAULT '', `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `index` int(11) unsigned NOT NULL DEFAULT 0, `type` enum('normal','broadcast','notify','bulletin') NOT NULL DEFAULT 'normal', `content` text NOT NULL, `contentType` enum('text','plain','emotion','image','file','object','code') NOT NULL DEFAULT 'text', @@ -1196,6 +1203,7 @@ CREATE TABLE `zt_im_message_backup` ( `cgid` char(40) NOT NULL DEFAULT '', `user` varchar(30) NOT NULL DEFAULT '', `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `index` int(11) unsigned NOT NULL DEFAULT 0, `type` enum('normal','broadcast','notify') NOT NULL DEFAULT 'normal', `content` text NOT NULL, `contentType` enum('text','plain','emotion','image','file','object','code') NOT NULL DEFAULT 'text', @@ -2560,6 +2568,8 @@ CREATE TABLE `zt_story` ( `approvedDate` date NOT NULL, `lastEditedBy` varchar(30) NOT NULL DEFAULT '', `lastEditedDate` 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 '', @@ -3180,6 +3190,7 @@ CREATE TABLE `zt_workflowaction` ( `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', `virtual` tinyint(1) unsigned NOT NULL, `conditions` text NOT NULL, `verifications` text NOT NULL, @@ -3241,6 +3252,7 @@ CREATE TABLE `zt_workflowfield` ( `isValue` enum('0','1') NOT NULL DEFAULT '0', `readonly` enum('0','1') NOT NULL DEFAULT '0', `buildin` tinyint(1) unsigned NOT NULL, + `role` varchar(10) NOT NULL DEFAULT 'custom', `desc` text NOT NULL, `createdBy` varchar(30) NOT NULL, `createdDate` datetime NOT NULL, @@ -3262,6 +3274,7 @@ CREATE TABLE `zt_workflowlabel` ( `orderBy` text NOT NULL, `order` tinyint(3) NOT NULL, `buildin` tinyint(1) unsigned NOT NULL, + `role` varchar(10) NOT NULL DEFAULT 'custom', `createdBy` char(30) NOT NULL, `createdDate` datetime NOT NULL, `editedBy` char(30) NOT NULL, diff --git a/db/update17.1.sql b/db/update17.1.sql index 15d43d1d73..cacf357ed6 100644 --- a/db/update17.1.sql +++ b/db/update17.1.sql @@ -18,4 +18,21 @@ ALTER TABLE `zt_kanban` ADD `showWIP` enum('0','1') NOT NULL DEFAULT '1' AFTER ` ALTER TABLE `zt_kanban` ADD `alignment` varchar(10) NOT NULL DEFAULT 'center' AFTER `object`; ALTER TABLE `zt_module` ADD `from` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `type`; -ALTER TABLE `zt_workflow` ADD `approval` enum('enabled', 'disabled') NOT NULL DEFAULT 'disabled' AFTER `status`; \ No newline at end of file + +ALTER TABLE `zt_story` ADD `changedBy` VARCHAR(30) NOT NULL AFTER `lastEditedDate`; +ALTER TABLE `zt_story` ADD `changedDate` DATETIME NOT NULL AFTER `changedBy`; + +ALTER TABLE `zt_action` CHANGE `id` `id` int(9) unsigned NOT NULL AUTO_INCREMENT FIRST; +ALTER TABLE `zt_history` CHANGE `id` `id` int(9) unsigned NOT NULL AUTO_INCREMENT FIRST; + +ALTER TABLE `zt_workflow` ADD `approval` enum('enabled', 'disabled') NOT NULL DEFAULT 'disabled' AFTER `status`; +ALTER TABLE `zt_workflowaction` ADD `role` varchar(10) NOT NULL DEFAULT 'custom' AFTER `buildin`; +ALTER TABLE `zt_workflowfield` ADD `role` varchar(10) NOT NULL DEFAULT 'custom' AFTER `buildin`; +ALTER TABLE `zt_workflowlabel` ADD `role` varchar(10) NOT NULL DEFAULT 'custom' AFTER `buildin`; + +UPDATE `zt_workflowaction` SET `role` = 'buildin' WHERE `role` = 'custom' AND `buildin` = '1'; +UPDATE `zt_workflowaction` SET `role` = 'virtual' WHERE `role` = 'custom' AND `virtual` = '1'; +UPDATE `zt_workflowaction` SET `role` = 'default' WHERE `role` = 'custom' AND `action` IN ('browse', 'create', 'batchcreate', 'edit', 'view', 'delete', 'link', 'unlink', 'export', 'exporttemplate', 'import', 'showimport', 'report', 'assign', 'batchedit', 'batchassign'); +UPDATE `zt_workflowfield` SET `role` = 'buildin' WHERE `role` = 'custom' AND (`buildin` = '1' OR `field` = 'subStatus'); +UPDATE `zt_workflowfield` SET `role` = 'default' WHERE `role` = 'custom' AND `field` IN ('id', 'parent', 'assignedTo', 'status', 'createdBy', 'createdDate', 'editedBy', 'editedDate', 'assignedBy', 'assignedDate' 'mailto', 'deleted'); +UPDATE `zt_workflowlabel` SET `role` = 'buildin' WHERE `role` = 'custom' AND `buildin` = '1'; diff --git a/db/zentao.sql b/db/zentao.sql index f5aba4dff7..84a4bb10af 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS `zt_acl` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_action`; CREATE TABLE IF NOT EXISTS `zt_action` ( - `id` mediumint(8) unsigned NOT NULL auto_increment, + `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, @@ -705,7 +705,7 @@ CREATE TABLE IF NOT EXISTS `zt_holiday` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_history`; CREATE TABLE IF NOT EXISTS `zt_history` ( - `id` mediumint(8) unsigned NOT NULL auto_increment, + `id` int(9) unsigned NOT NULL auto_increment, `action` mediumint(8) unsigned NOT NULL default '0', `field` varchar(30) NOT NULL default '', `old` text NOT NULL, @@ -1397,6 +1397,8 @@ CREATE TABLE IF NOT EXISTS `zt_story` ( `assignedDate` datetime NOT NULL, `lastEditedBy` varchar(30) NOT NULL default '', `lastEditedDate` 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 '', @@ -6140,6 +6142,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat` ( `mergedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `lastActiveTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `lastMessage` int(11) unsigned NOT NULL DEFAULT 0, + `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 '', @@ -6166,6 +6169,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_chatuser` ( `quit` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `category` varchar(40) NOT NULL DEFAULT '', `lastReadMessage` int(11) unsigned NOT NULL DEFAULT 0, + `lastReadMessageIndex` int(11) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `cgid` (`cgid`), KEY `user` (`user`), @@ -6198,6 +6202,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_message` ( `cgid` char(40) NOT NULL DEFAULT '', `user` varchar(30) NOT NULL DEFAULT '', `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `index` int(11) unsigned NOT NULL DEFAULT 0, `type` enum('normal', 'broadcast', 'notify', 'bulletin') NOT NULL DEFAULT 'normal', `content` text NOT NULL DEFAULT '', `contentType` enum('text', 'plain', 'emotion', 'image', 'file', 'object', 'code') NOT NULL DEFAULT 'text', @@ -6217,6 +6222,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_message_backup` ( `cgid` char(40) NOT NULL DEFAULT '', `user` varchar(30) NOT NULL DEFAULT '', `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `index` int(11) unsigned NOT NULL DEFAULT 0, `type` enum('normal', 'broadcast', 'notify') NOT NULL DEFAULT 'normal', `content` text NOT NULL DEFAULT '', `contentType` enum('text', 'plain', 'emotion', 'image', 'file', 'object', 'code') NOT NULL DEFAULT 'text', @@ -6248,6 +6254,8 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat_message_index` ( `tableName` char(64) NOT NULL, `start` int(11) unsigned NOT NULL, `end` int(11) unsigned NOT NULL, + `startIndex` int(11) unsigned NOT NULL, + `endIndex` int(11) unsigned NOT NULL, `startDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `endDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `count` mediumint(8) unsigned NOT NULL, @@ -6256,7 +6264,9 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat_message_index` ( KEY `start` (`start`), KEY `end` (`end`), KEY `startDate` (`startDate`), - KEY `endDate` (`endDate`) + KEY `endDate` (`endDate`), + KEY `chatstartindex` (`gid`,`startIndex`), + KEY `chatendindex` (`gid`,`endIndex`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_im_messagestatus`; @@ -8524,6 +8534,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowaction` ( `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', `virtual` tinyint(1) unsigned NOT NULL, `conditions` text NOT NULL, `verifications` text NOT NULL, @@ -8587,6 +8598,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowfield` ( `isValue` enum('0', '1') NOT NULL DEFAULT '0', `readonly` enum('0', '1') NOT NULL DEFAULT '0', `buildin` tinyint(1) unsigned NOT NULL, + `role` varchar(10) NOT NULL DEFAULT 'custom', `desc` text NOT NULL, `createdBy` varchar(30) NOT NULL, `createdDate` datetime NOT NULL, @@ -8631,6 +8643,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowlabel` ( `orderBy` text NOT NULL, `order` tinyint(3) NOT NULL, `buildin` tinyint(1) unsigned NOT NULL, + `role` varchar(10) NOT NULL DEFAULT 'custom', `createdBy` char(30) NOT NULL, `createdDate` datetime NOT NULL, `editedBy` char(30) NOT NULL, @@ -13480,12 +13493,7 @@ REPLACE INTO `zt_zoutput` (`id`, `activity`, `name`, `content`, `optional`, `tai (246, 163, '《配置审计报告》', '', 'yes', '', '', 'admin', '2020-01-09 14:55:08', '', '0000-00-00 00:00:00', 605, '0'), (247, 166, '《度量分析计划》', '', 'yes', '', '', 'admin', '2020-01-09 14:55:08', '', '0000-00-00 00:00:00', 610, '0'), (248, 168, '项目度量数据库', '', 'yes', '', '', 'admin', '2020-01-09 14:55:08', '', '0000-00-00 00:00:00', 615, '0'), -(249, 172, '《量化项目管理及跟踪计划》', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 620, '0'), -(250, 170, '《决策分析报告》的决策分析评估表', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 625, '0'), -(251, 169, '《量化项目计划及跟踪表》', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 630, '0'), -(252, 173, '《决策分析报告》的评分表', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 635, '0'), -(253, 174, '《决策分析报告》的评分表', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 640, '0'), -(254, 175, '《决策分析报告》', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 645, '0'); +(249, 169, '《量化项目计划及跟踪表》', '', 'no', '', '', 'admin', '2020-01-09 14:59:04', '', '0000-00-00 00:00:00', 630, '0'); REPLACE INTO `zt_basicmeas` VALUES (2,'scale','project','userRequest','项目用户需求初始规模','pgmURInitScale','故事点或功能点','CREATE FUNCTION qc_pgmurinitscale($project int) returns float (10,2)\r\nbegin\r\n declare scale float(10,2) default 0__DELIMITER__\r\n declare inited int default 0__DELIMITER__\r\n select qc_cminited($project, \'URS\') into inited__DELIMITER__\r\n IF inited = 1 THEN\r\n select qc_initscale($project, \'URS\',\'requestEst\') into scale__DELIMITER__\r\n return scale__DELIMITER__\r\n ELSE \r\n return 0__DELIMITER__\r\n END IF__DELIMITER__\r\nend','{\"$project\":{\"showName\":\"\\u6240\\u5c5e\\u9879\\u76ee\",\"varName\":\"$project\",\"varType\":\"select\",\"options\":\"project\",\"defaultValue\":\"\"}}','项目每个产品的第一个用户需求规格说明书基线版本的规模之和','从基线表中查询该项目下面每个产品的第一个用户需求规模说明书版本,然后查询对应的需求,求和。','crontab','{\"week\":\"1,2,3,4,5,6,0\",\"type\":\"week\"}','00:00','','system','0000-00-00 00:00:00','admin','2020-07-07 14:19:41',10,'0'), diff --git a/extension/lite/action/ext/lang/de/lite.php b/extension/lite/action/ext/lang/de/lite.php index fb0fcbad1b..954a91a744 100644 --- a/extension/lite/action/ext/lang/de/lite.php +++ b/extension/lite/action/ext/lang/de/lite.php @@ -59,9 +59,9 @@ $lang->action->dynamicAction->task['linkchildtask'] = 'Link child Task'; $lang->action->label->createchildrenstory = "Create child story"; $lang->action->label->linkchildstory = "Link child story"; -$lang->action->label->unlinkchildrenstory = "CanceledLink child story"; +$lang->action->label->unlinkchildrenstory = "unlinked a child story"; $lang->action->label->linkparentstory = "Link parent story"; -$lang->action->label->unlinkparentstory = "From parent storyCanceledLink"; +$lang->action->label->unlinkparentstory = "CanceledLink from parent story "; $lang->action->label->deletechildrenstory = "Deleted child story"; $lang->action->search->label = array(); @@ -101,13 +101,6 @@ $lang->action->search->label['verified'] = $lang->action->label->ve $lang->action->search->label['login'] = $lang->action->label->login; $lang->action->search->label['logout'] = $lang->action->label->logout; -$lang->action->label->createchildrenstory = "Create child story"; -$lang->action->label->linkchildstory = "Link child story"; -$lang->action->label->unlinkchildrenstory = "unlinked a child story"; -$lang->action->label->linkparentstory = "Link parent story"; -$lang->action->label->unlinkparentstory = "CanceledLink from parent story "; -$lang->action->label->deletechildrenstory = "Deleted child story"; - $lang->action->desc->createchildrenstory = '$date, $actor Create child story $extra。' . "\n"; $lang->action->desc->linkchildstory = '$date, $actor Link child story $extra。' . "\n"; $lang->action->desc->unlinkchildrenstory = '$date, $actor Unlink child story $extra。' . "\n"; diff --git a/extension/lite/action/ext/lang/en/lite.php b/extension/lite/action/ext/lang/en/lite.php index fb0fcbad1b..954a91a744 100644 --- a/extension/lite/action/ext/lang/en/lite.php +++ b/extension/lite/action/ext/lang/en/lite.php @@ -59,9 +59,9 @@ $lang->action->dynamicAction->task['linkchildtask'] = 'Link child Task'; $lang->action->label->createchildrenstory = "Create child story"; $lang->action->label->linkchildstory = "Link child story"; -$lang->action->label->unlinkchildrenstory = "CanceledLink child story"; +$lang->action->label->unlinkchildrenstory = "unlinked a child story"; $lang->action->label->linkparentstory = "Link parent story"; -$lang->action->label->unlinkparentstory = "From parent storyCanceledLink"; +$lang->action->label->unlinkparentstory = "CanceledLink from parent story "; $lang->action->label->deletechildrenstory = "Deleted child story"; $lang->action->search->label = array(); @@ -101,13 +101,6 @@ $lang->action->search->label['verified'] = $lang->action->label->ve $lang->action->search->label['login'] = $lang->action->label->login; $lang->action->search->label['logout'] = $lang->action->label->logout; -$lang->action->label->createchildrenstory = "Create child story"; -$lang->action->label->linkchildstory = "Link child story"; -$lang->action->label->unlinkchildrenstory = "unlinked a child story"; -$lang->action->label->linkparentstory = "Link parent story"; -$lang->action->label->unlinkparentstory = "CanceledLink from parent story "; -$lang->action->label->deletechildrenstory = "Deleted child story"; - $lang->action->desc->createchildrenstory = '$date, $actor Create child story $extra。' . "\n"; $lang->action->desc->linkchildstory = '$date, $actor Link child story $extra。' . "\n"; $lang->action->desc->unlinkchildrenstory = '$date, $actor Unlink child story $extra。' . "\n"; diff --git a/extension/lite/action/ext/lang/fr/lite.php b/extension/lite/action/ext/lang/fr/lite.php index fb0fcbad1b..954a91a744 100644 --- a/extension/lite/action/ext/lang/fr/lite.php +++ b/extension/lite/action/ext/lang/fr/lite.php @@ -59,9 +59,9 @@ $lang->action->dynamicAction->task['linkchildtask'] = 'Link child Task'; $lang->action->label->createchildrenstory = "Create child story"; $lang->action->label->linkchildstory = "Link child story"; -$lang->action->label->unlinkchildrenstory = "CanceledLink child story"; +$lang->action->label->unlinkchildrenstory = "unlinked a child story"; $lang->action->label->linkparentstory = "Link parent story"; -$lang->action->label->unlinkparentstory = "From parent storyCanceledLink"; +$lang->action->label->unlinkparentstory = "CanceledLink from parent story "; $lang->action->label->deletechildrenstory = "Deleted child story"; $lang->action->search->label = array(); @@ -101,13 +101,6 @@ $lang->action->search->label['verified'] = $lang->action->label->ve $lang->action->search->label['login'] = $lang->action->label->login; $lang->action->search->label['logout'] = $lang->action->label->logout; -$lang->action->label->createchildrenstory = "Create child story"; -$lang->action->label->linkchildstory = "Link child story"; -$lang->action->label->unlinkchildrenstory = "unlinked a child story"; -$lang->action->label->linkparentstory = "Link parent story"; -$lang->action->label->unlinkparentstory = "CanceledLink from parent story "; -$lang->action->label->deletechildrenstory = "Deleted child story"; - $lang->action->desc->createchildrenstory = '$date, $actor Create child story $extra。' . "\n"; $lang->action->desc->linkchildstory = '$date, $actor Link child story $extra。' . "\n"; $lang->action->desc->unlinkchildrenstory = '$date, $actor Unlink child story $extra。' . "\n"; diff --git a/extension/lite/action/ext/lang/zh-cn/lite.php b/extension/lite/action/ext/lang/zh-cn/lite.php index 7c12ffc960..e350a4d18e 100644 --- a/extension/lite/action/ext/lang/zh-cn/lite.php +++ b/extension/lite/action/ext/lang/zh-cn/lite.php @@ -101,13 +101,6 @@ $lang->action->search->label['verified'] = $lang->action->label->ve $lang->action->search->label['login'] = $lang->action->label->login; $lang->action->search->label['logout'] = $lang->action->label->logout; -$lang->action->label->createchildrenstory = "创建子目标"; -$lang->action->label->linkchildstory = "关联子目标"; -$lang->action->label->unlinkchildrenstory = "取消关联子目标"; -$lang->action->label->linkparentstory = "关联到父目标"; -$lang->action->label->unlinkparentstory = "从父目标取消关联"; -$lang->action->label->deletechildrenstory = "删除子目标"; - $lang->action->desc->createchildrenstory = '$date, 由 $actor 创建子目标 $extra。' . "\n"; $lang->action->desc->linkchildstory = '$date, 由 $actor 关联子目标 $extra。' . "\n"; $lang->action->desc->unlinkchildrenstory = '$date, 由 $actor 移除子目标 $extra。' . "\n"; diff --git a/extension/lite/attend/ext/view/stat.oa.html.hook.php b/extension/lite/attend/ext/view/stat.oa.html.hook.php deleted file mode 100644 index c5c67c3735..0000000000 --- a/extension/lite/attend/ext/view/stat.oa.html.hook.php +++ /dev/null @@ -1,3 +0,0 @@ -getExtensionRoot() . '/biz/attend/ext/view/stat.oa.html.hook.php'; -?> \ No newline at end of file diff --git a/extension/lite/custom/ext/lang/de/lite.php b/extension/lite/custom/ext/lang/de/lite.php index adc8835faf..7b4a6e67f3 100644 --- a/extension/lite/custom/ext/lang/de/lite.php +++ b/extension/lite/custom/ext/lang/de/lite.php @@ -13,6 +13,14 @@ $lang->custom->object['todo'] = 'Todo'; $lang->custom->object['user'] = 'User'; $lang->custom->object['block'] = 'Block'; +$lang->custom->menuOrder = array(); +$lang->custom->menuOrder[10] = 'execution'; +$lang->custom->menuOrder[15] = 'story'; +$lang->custom->menuOrder[20] = 'task'; +$lang->custom->menuOrder[25] = 'todo'; +$lang->custom->menuOrder[30] = 'user'; +$lang->custom->menuOrder[35] = 'block'; + $lang->custom->task = new stdClass(); $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; diff --git a/extension/lite/custom/ext/lang/en/lite.php b/extension/lite/custom/ext/lang/en/lite.php index adc8835faf..7b4a6e67f3 100644 --- a/extension/lite/custom/ext/lang/en/lite.php +++ b/extension/lite/custom/ext/lang/en/lite.php @@ -13,6 +13,14 @@ $lang->custom->object['todo'] = 'Todo'; $lang->custom->object['user'] = 'User'; $lang->custom->object['block'] = 'Block'; +$lang->custom->menuOrder = array(); +$lang->custom->menuOrder[10] = 'execution'; +$lang->custom->menuOrder[15] = 'story'; +$lang->custom->menuOrder[20] = 'task'; +$lang->custom->menuOrder[25] = 'todo'; +$lang->custom->menuOrder[30] = 'user'; +$lang->custom->menuOrder[35] = 'block'; + $lang->custom->task = new stdClass(); $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; diff --git a/extension/lite/custom/ext/lang/fr/lite.php b/extension/lite/custom/ext/lang/fr/lite.php index adc8835faf..7b4a6e67f3 100644 --- a/extension/lite/custom/ext/lang/fr/lite.php +++ b/extension/lite/custom/ext/lang/fr/lite.php @@ -13,6 +13,14 @@ $lang->custom->object['todo'] = 'Todo'; $lang->custom->object['user'] = 'User'; $lang->custom->object['block'] = 'Block'; +$lang->custom->menuOrder = array(); +$lang->custom->menuOrder[10] = 'execution'; +$lang->custom->menuOrder[15] = 'story'; +$lang->custom->menuOrder[20] = 'task'; +$lang->custom->menuOrder[25] = 'todo'; +$lang->custom->menuOrder[30] = 'user'; +$lang->custom->menuOrder[35] = 'block'; + $lang->custom->task = new stdClass(); $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; diff --git a/extension/lite/feedback/ext/view/view.lite.html.hook.php b/extension/lite/feedback/ext/view/view.lite.html.hook.php new file mode 100644 index 0000000000..8ad5595c4d --- /dev/null +++ b/extension/lite/feedback/ext/view/view.lite.html.hook.php @@ -0,0 +1,3 @@ + diff --git a/extension/lite/flow/ext/view/browse.flow.html.hook.php b/extension/lite/flow/ext/view/browse.flow.html.hook.php deleted file mode 100644 index c66dc67377..0000000000 --- a/extension/lite/flow/ext/view/browse.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/flow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/flow/ext/view/create.flow.html.hook.php b/extension/lite/flow/ext/view/create.flow.html.hook.php deleted file mode 100644 index c66dc67377..0000000000 --- a/extension/lite/flow/ext/view/create.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/flow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/group/ext/lang/resource.php b/extension/lite/group/ext/lang/resource.php index de00c3c944..ec5c6714a9 100644 --- a/extension/lite/group/ext/lang/resource.php +++ b/extension/lite/group/ext/lang/resource.php @@ -551,8 +551,8 @@ $lang->resource->task->recordEstimate = 'recordEstimateAction'; $lang->resource->task->editEstimate = 'editEstimate'; $lang->resource->task->deleteEstimate = 'deleteEstimate'; $lang->resource->task->report = 'reportChart'; -$lang->resource->task->exportTemplet = 'exportTemplet'; -$lang->resource->task->import = 'import'; +if($config->edition != 'open') $lang->resource->task->exportTemplet = 'exportTemplet'; +if($config->edition != 'open') $lang->resource->task->import = 'import'; $lang->task->methodOrder[5] = 'create'; $lang->task->methodOrder[10] = 'batchCreate'; diff --git a/extension/lite/todo/ext/view/view.lite.html.hook.php b/extension/lite/todo/ext/view/view.lite.html.hook.php index fad3ee2b75..56bdae52d4 100644 --- a/extension/lite/todo/ext/view/view.lite.html.hook.php +++ b/extension/lite/todo/ext/view/view.lite.html.hook.php @@ -37,7 +37,7 @@ $('#toStoryLink').click(function() $('#toStoryButtonByProject').click(function() { var onlybody = config.onlybody == 'yes'; - var projectID = $('#projectToStory').val(); + var projectID = $('#projectToStory').val(); var link = createLink('story', 'create', 'productID=0&branch=0&moduleID=0&storyID=0&projectID=' + projectID + '&bugID=0&planID=0&todoID=' + todoID, config.defaultView, onlybody); if(!onlybody) window.parent.$.apps.open(link, 'project'); @@ -75,4 +75,4 @@ function createProject() config.onlybody = onlybody; parent.location.href = link; } - \ No newline at end of file + diff --git a/extension/lite/workflow/ext/view/browsedb.flow.html.hook.php b/extension/lite/workflow/ext/view/browsedb.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/browsedb.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/browseflow.flow.html.hook.php b/extension/lite/workflow/ext/view/browseflow.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/browseflow.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/copy.flow.html.hook.php b/extension/lite/workflow/ext/view/copy.flow.html.hook.php index bb1ebdd750..79974026e4 100644 --- a/extension/lite/workflow/ext/view/copy.flow.html.hook.php +++ b/extension/lite/workflow/ext/view/copy.flow.html.hook.php @@ -1,4 +1,3 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/edit.flow.html.hook.php b/extension/lite/workflow/ext/view/edit.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/edit.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/flowchart.flow.html.hook.php b/extension/lite/workflow/ext/view/flowchart.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/flowchart.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/release.flow.html.hook.php b/extension/lite/workflow/ext/view/release.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/release.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/setcss.flow.html.hook.php b/extension/lite/workflow/ext/view/setcss.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/setcss.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/setjs.flow.html.hook.php b/extension/lite/workflow/ext/view/setjs.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/setjs.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflow/ext/view/ui.flow.html.hook.php b/extension/lite/workflow/ext/view/ui.flow.html.hook.php deleted file mode 100644 index 2dbe26bf06..0000000000 --- a/extension/lite/workflow/ext/view/ui.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflow/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowaction/ext/view/browse.flow.html.hook.php b/extension/lite/workflowaction/ext/view/browse.flow.html.hook.php deleted file mode 100644 index 9a25285d22..0000000000 --- a/extension/lite/workflowaction/ext/view/browse.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowaction/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowaction/ext/view/create.flow.html.hook.php b/extension/lite/workflowaction/ext/view/create.flow.html.hook.php index 6c51eeb21c..b0f336e568 100644 --- a/extension/lite/workflowaction/ext/view/create.flow.html.hook.php +++ b/extension/lite/workflowaction/ext/view/create.flow.html.hook.php @@ -1,4 +1,3 @@ -app->getExtensionRoot() . 'biz/workflowaction/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowaction/ext/view/edit.flow.html.hook.php b/extension/lite/workflowaction/ext/view/edit.flow.html.hook.php deleted file mode 100644 index 9a25285d22..0000000000 --- a/extension/lite/workflowaction/ext/view/edit.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowaction/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowaction/ext/view/setnotice.flow.html.hook.php b/extension/lite/workflowaction/ext/view/setnotice.flow.html.hook.php deleted file mode 100644 index 9a25285d22..0000000000 --- a/extension/lite/workflowaction/ext/view/setnotice.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowaction/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowdatasource/ext/view/browse.flow.html.hook.php b/extension/lite/workflowdatasource/ext/view/browse.flow.html.hook.php deleted file mode 100644 index e029265b5e..0000000000 --- a/extension/lite/workflowdatasource/ext/view/browse.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowdatasource/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowdatasource/ext/view/create.flow.html.hook.php b/extension/lite/workflowdatasource/ext/view/create.flow.html.hook.php index 55d057a936..fefcab51f4 100644 --- a/extension/lite/workflowdatasource/ext/view/create.flow.html.hook.php +++ b/extension/lite/workflowdatasource/ext/view/create.flow.html.hook.php @@ -3,4 +3,3 @@ $('#submit').after(' -app->getExtensionRoot() . 'biz/workflowdatasource/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowdatasource/ext/view/edit.flow.html.hook.php b/extension/lite/workflowdatasource/ext/view/edit.flow.html.hook.php deleted file mode 100644 index e029265b5e..0000000000 --- a/extension/lite/workflowdatasource/ext/view/edit.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowdatasource/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowfield/ext/view/browse.flow.html.hook.php b/extension/lite/workflowfield/ext/view/browse.flow.html.hook.php deleted file mode 100644 index 11369cc5af..0000000000 --- a/extension/lite/workflowfield/ext/view/browse.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowfield/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowfield/ext/view/edit.flow.html.hook.php b/extension/lite/workflowfield/ext/view/edit.flow.html.hook.php index 122e39595d..50342ecd4b 100644 --- a/extension/lite/workflowfield/ext/view/edit.flow.html.hook.php +++ b/extension/lite/workflowfield/ext/view/edit.flow.html.hook.php @@ -1,4 +1,3 @@ -app->getExtensionRoot() . 'biz/workflowfield/ext/view/' . basename(__FILE__);?> visions == ',lite,'):?> dao->select('id')->from(TABLE_WORKFLOWDATASOURCE)->where('code')->like('litefeedback%')->andWhere('vision')->eq('lite')->fetchPairs('id', 'id');?> diff --git a/extension/lite/workflowhook/ext/view/create.flow.html.hook.php b/extension/lite/workflowhook/ext/view/create.flow.html.hook.php deleted file mode 100644 index abebb6d16b..0000000000 --- a/extension/lite/workflowhook/ext/view/create.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowhook/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowhook/ext/view/edit.flow.html.hook.php b/extension/lite/workflowhook/ext/view/edit.flow.html.hook.php deleted file mode 100644 index abebb6d16b..0000000000 --- a/extension/lite/workflowhook/ext/view/edit.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowhook/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowlabel/ext/view/browse.flow.html.hook.php b/extension/lite/workflowlabel/ext/view/browse.flow.html.hook.php deleted file mode 100644 index d32409775c..0000000000 --- a/extension/lite/workflowlabel/ext/view/browse.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowlabel/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowlayout/ext/view/admin.flow.html.hook.php b/extension/lite/workflowlayout/ext/view/admin.flow.html.hook.php deleted file mode 100644 index 038a427205..0000000000 --- a/extension/lite/workflowlayout/ext/view/admin.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowlayout/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowrelation/ext/view/admin.flow.html.hook.php b/extension/lite/workflowrelation/ext/view/admin.flow.html.hook.php deleted file mode 100644 index 09020f0aad..0000000000 --- a/extension/lite/workflowrelation/ext/view/admin.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowrelation/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowrule/ext/view/browse.flow.html.hook.php b/extension/lite/workflowrule/ext/view/browse.flow.html.hook.php deleted file mode 100644 index 06a563562d..0000000000 --- a/extension/lite/workflowrule/ext/view/browse.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowrule/ext/view/' . basename(__FILE__);?> diff --git a/extension/lite/workflowrule/ext/view/view.flow.html.hook.php b/extension/lite/workflowrule/ext/view/view.flow.html.hook.php deleted file mode 100644 index 06a563562d..0000000000 --- a/extension/lite/workflowrule/ext/view/view.flow.html.hook.php +++ /dev/null @@ -1 +0,0 @@ -app->getExtensionRoot() . 'biz/workflowrule/ext/view/' . basename(__FILE__);?> diff --git a/framework/base/router.class.php b/framework/base/router.class.php index 03af29a265..d112ebe7f9 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -2831,6 +2831,17 @@ class baseRouter fwrite($fh, "\n"); fclose($fh); } + + /** + * Check app if it is run in a container. + * + * @access public + * @return bool + */ + public function isContainer() + { + return strtolower(getenv('IS_CONTAINER')) == 'true'; + } } /** diff --git a/lib/base/front/front.class.php b/lib/base/front/front.class.php index 4c18838dfb..9afe2605e6 100644 --- a/lib/base/front/front.class.php +++ b/lib/base/front/front.class.php @@ -501,8 +501,6 @@ class baseHTML $gobackList = isset($_COOKIE['goback']) ? json_decode($_COOKIE['goback'], true) : array(); $gobackLink = isset($gobackList[$tab]) ? $gobackList[$tab] : ''; - if(strpos($misc, 'data-app') === false) $misc .= " data-app='" . $tab . "'"; - /* If the link of the referer is not the link of the current page or the link of the index, the cookie and gobackLink will be updated. */ if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", strtolower($refererLink))) { diff --git a/lib/scm/gitrepo.class.php b/lib/scm/gitrepo.class.php index 93261cdcac..2b691eef17 100644 --- a/lib/scm/gitrepo.class.php +++ b/lib/scm/gitrepo.class.php @@ -107,6 +107,12 @@ class GitRepo $cmd = escapeCmd("$this->client tag --sort=taggerdate"); $list = execCmd($cmd . ' 2>&1', 'array', $result); if($result) return array(); + + foreach($list as $key => $tag) + { + if(!$tag) unset($list[$key]); + } + return $list; } @@ -139,7 +145,7 @@ class GitRepo } asort($branches); - $branches = array($defaultBranch => $defaultBranch) + $branches; + if($defaultBranch) $branches = array($defaultBranch => $defaultBranch) + $branches; return $branches; } diff --git a/module/action/model.php b/module/action/model.php index 3df166a917..0a515a7cd4 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -985,9 +985,9 @@ class actionModel extends model } $condition = "((product =',0,' or product=0) AND project = '0' AND execution = 0)"; - if(isset($productCondition)) $condition .= ' OR ' . $productCondition; - if(isset($projectCondition)) $condition .= ' OR ' . $projectCondition; - if(isset($executionCondition)) $condition .= ' OR ' . $executionCondition; + if(!empty($productCondition)) $condition .= ' OR ' . $productCondition; + if(!empty($projectCondition)) $condition .= ' OR ' . $projectCondition; + if(!empty($executionCondition)) $condition .= ' OR ' . $executionCondition; } $actionCondition = $this->getActionCondition(); diff --git a/module/api/control.php b/module/api/control.php index d0d3eff2fa..2601e6e871 100755 --- a/module/api/control.php +++ b/module/api/control.php @@ -251,9 +251,10 @@ class api extends control $id = $this->api->createStruct($data); + if(dao::isError()) return $this->sendError(dao::getError()); + $this->action->create('apistruct', $id, 'Created'); - if(dao::isError()) return $this->sendError(dao::getError()); return $this->sendSuccess(array('locate' => helper::createLink('api', 'struct', "libID=$libID"))); } @@ -455,7 +456,7 @@ class api extends control $this->getTypeOptions($api->lib); $this->view->title = $api->title . $this->lang->api->edit; - $this->view->gobackLink = $this->createLink('api', 'index', "libID={$api->lib}&moduleID={$api->module}"); + $this->view->gobackLink = $this->createLink('api', 'index', "libID={$api->lib}&moduleID={$api->module}&apiID=$apiID"); $this->view->user = $this->app->user->account; $this->view->allUsers = $this->loadModel('user')->getPairs('devfirst|noclosed');; $this->view->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($api->lib, 'api', $startModuleID = 0); diff --git a/module/api/model.php b/module/api/model.php index 539132b98a..4b121cc395 100644 --- a/module/api/model.php +++ b/module/api/model.php @@ -910,7 +910,7 @@ class apiModel extends model $this->config->api->search['module'] = 'api'; $this->config->api->search['queryID'] = $queryID; $this->config->api->search['actionURL'] = $actionURL; - $this->config->api->search['params']['lib']['values'] = array($lib->id => $lib->name) + array('all' => $this->lang->api->allLibs); + $this->config->api->search['params']['lib']['values'] = (!empty($lib)) ? array($lib->id => $lib->name) + array('all' => $this->lang->api->allLibs) : array('all' => $this->lang->api->allLibs); $this->loadModel('search')->setSearchParams($this->config->api->search); } diff --git a/module/api/view/createlib.html.php b/module/api/view/createlib.html.php index 1699aadaa2..4f29e96290 100644 --- a/module/api/view/createlib.html.php +++ b/module/api/view/createlib.html.php @@ -33,7 +33,8 @@ api->control;?> - api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")'")?> + + api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")' $isDisabled")?> api->noticeAcl['open'];?> diff --git a/module/block/control.php b/module/block/control.php index 7af7fdf698..3e1b93299b 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -1079,10 +1079,10 @@ class block extends control /* Get tasks. Fix bug #2918.*/ $yesterday = date('Y-m-d', strtotime('-1 day')); - $taskGroups = $this->dao->select("id,parent,project,status,finishedDate,estimate,consumed,`left`")->from(TABLE_TASK) - ->where('project')->in($executionIdList) + $taskGroups = $this->dao->select("id,parent,execution,status,finishedDate,estimate,consumed,`left`")->from(TABLE_TASK) + ->where('execution')->in($executionIdList) ->andWhere('deleted')->eq(0) - ->fetchGroup('project', 'id'); + ->fetchGroup('execution', 'id'); $tasks = array(); foreach($taskGroups as $executionID => $taskGroup) @@ -1095,7 +1095,7 @@ class block extends control foreach($taskGroup as $taskID => $task) { - if(strpos('wait|doing|pause', $task->status) !== false) $undoneTasks ++; + if(strpos('wait|doing|pause|cancel', $task->status) !== false) $undoneTasks ++; if(strpos($task->finishedDate, $yesterday) !== false) $yesterdayFinished ++; if($task->parent == '-1') continue; @@ -1131,11 +1131,11 @@ class block extends control } /* Get bugs. */ - $bugs = $this->dao->select("project, count(status) as totalBugs, count(status = 'active' or null) as activeBugs, count(resolvedDate like '{$yesterday}%' or null) as yesterdayResolved")->from(TABLE_BUG) - ->where('project')->in($executionIdList) + $bugs = $this->dao->select("execution, count(status) as totalBugs, count(status = 'active' or null) as activeBugs, count(resolvedDate like '{$yesterday}%' or null) as yesterdayResolved")->from(TABLE_BUG) + ->where('execution')->in($executionIdList) ->andWhere('deleted')->eq(0) - ->groupBy('project') - ->fetchAll('project'); + ->groupBy('execution') + ->fetchAll('execution'); foreach($bugs as $executionID => $bug) { diff --git a/module/block/model.php b/module/block/model.php index 62fe91b209..baaa0b6be0 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -34,6 +34,7 @@ class blockModel extends model ->setDefault('grid', '4') ->setDefault('source', $source) ->setDefault('block', $type) + ->setDefault('vision', $this->config->vision) ->setDefault('params', array()) ->remove('uid,actionLink,modules,moduleBlock') ->get(); diff --git a/module/block/view/executionstatisticblock.html.php b/module/block/view/executionstatisticblock.html.php index bc8168dd0c..7a90a10d75 100644 --- a/module/block/view/executionstatisticblock.html.php +++ b/module/block/view/executionstatisticblock.html.php @@ -185,11 +185,11 @@ $(function() - + - +
bug->allBugs;?> :totalBugs) ? 0 : html::a($this->createLink('execution', 'bug', "executionID={$execution->id}&orderBy=status,id_desc&build=0&type=all"), $execution->totalBugs);?>totalBugs) ? 0 : html::a($this->createLink('execution', 'bug', "executionID={$execution->id}&productID=0&orderBy=status,id_desc&build=0&type=all"), $execution->totalBugs);?>
bug->unResolved;?> :activeBugs) ? 0 : html::a($this->createLink('execution', 'bug', "executionID={$execution->id}&orderBy=status,id_desc&build=0&type=unresolved"), $execution->activeBugs);?>activeBugs) ? 0 : html::a($this->createLink('execution', 'bug', "executionID={$execution->id}&productID=0&orderBy=status,id_desc&build=0&type=unresolved"), $execution->activeBugs);?>
diff --git a/module/block/view/main.html.php b/module/block/view/main.html.php index d90a21d363..debaacd1b0 100644 --- a/module/block/view/main.html.php +++ b/module/block/view/main.html.php @@ -10,6 +10,7 @@ * @link http://www.zentao.pms */ $viewDir = dirname(__FILE__); -$file2Include = file_exists(dirname($viewDir) . "/ext/view/{$code}block.html.php") ? dirname($viewDir) . "/ext/view/{$code}block.html.php" : "{$viewDir}/{$code}block.html.php"; +$extFire = $app->getExtensionRoot() . $config->edition . "/block/ext/view/{$code}block.html.php"; +$file2Include = file_exists($extFire) ? $extFire : "{$viewDir}/{$code}block.html.php"; include $file2Include; ?> diff --git a/module/bug/control.php b/module/bug/control.php index 9d14a7a01c..5b8fa4fcf7 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -2259,6 +2259,13 @@ class bug extends control $bug->steps = str_replace(' ', ' ', $bug->steps); } + $bug->openedDate = !helper::isZeroDate($bug->openedDate) ? $bug->openedDate : ''; + $bug->assignedDate = !helper::isZeroDate($bug->assignedDate) ? $bug->assignedDate : ''; + $bug->resolvedDate = !helper::isZeroDate($bug->resolvedDate) ? $bug->resolvedDate : ''; + $bug->closedDate = !helper::isZeroDate($bug->closedDate) ? $bug->closedDate : ''; + $bug->lastEditedDate = !helper::isZeroDate($bug->lastEditedDate) ? $bug->lastEditedDate : ''; + $bug->deadline = !helper::isZeroDate($bug->deadline) ? $bug->deadline : ''; + /* fill some field with useful value. */ $bug->product = !isset($products[$bug->product]) ? '' : $products[$bug->product] . "(#$bug->product)"; $bug->project = !isset($projects[$bug->project]) ? '' : $projects[$bug->project] . "(#$bug->project)"; diff --git a/module/bug/css/browse.css b/module/bug/css/browse.css index f28860922b..7a2518c139 100644 --- a/module/bug/css/browse.css +++ b/module/bug/css/browse.css @@ -34,3 +34,4 @@ body {margin-bottom: 25px;} .btn-group a.btn-primary {border-right: 1px solid rgba(255,255,255,0.3);} .btn-group button.dropdown-toggle.btn-primary {padding:6px;} #bugForm tbody tr td .label {max-width: 100px; text-overflow: unset;} +[lang^='de'] th.c-confirmed {width: 100px !important;} diff --git a/module/bug/lang/fr.php b/module/bug/lang/fr.php index 68341def99..e04e481637 100644 --- a/module/bug/lang/fr.php +++ b/module/bug/lang/fr.php @@ -425,7 +425,6 @@ $lang->bug->placeholder->newBuildName = 'Nom Nouv Build'; $lang->bug->featureBar['browse']['all'] = $lang->bug->allBugs; $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed; -$lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe; $lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe; $lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe; @@ -433,6 +432,7 @@ $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; $lang->bug->moreSelects['assignedbyme'] = $lang->bug->assignedByMe; +$lang->bug->moreSelects['openedbyme'] = $lang->bug->openedByMe; $lang->bug->moreSelects['unconfirmed'] = $lang->bug->unconfirmed; $lang->bug->moreSelects['assigntonull'] = $lang->bug->assignToNull; $lang->bug->moreSelects['longlifebugs'] = $lang->bug->longLifeBugs; diff --git a/module/bug/model.php b/module/bug/model.php index 236f66bef3..4ae5817b6f 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -3204,11 +3204,11 @@ class bugModel extends model $buildID = zget($builds, $build, ''); if($buildID == 'trunk') { - echo $build; + echo $build . ' '; } elseif($buildID and common::hasPriv('build', 'view')) { - echo html::a(helper::createLink('build', 'view', "buildID=$buildID"), $build, '', "title='$bug->openedBuild'"); + echo html::a(helper::createLink('build', 'view', "buildID=$buildID"), $build, '', "title='$bug->openedBuild'") . ' '; } } break; diff --git a/module/build/model.php b/module/build/model.php index 1eb43db7ef..dab588ecb5 100644 --- a/module/build/model.php +++ b/module/build/model.php @@ -549,7 +549,7 @@ class buildModel extends model if(common::hasPriv('build', 'linkstory') and common::canBeChanged('build', $build)) $menu .= $this->buildMenu('build', 'view', "{$params}&type=story&link=true", $build, $type, 'link', '', '', '', "data-app={$tab}", $this->lang->build->linkStory); - $menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id", $build, $type, 'bullhorn', '', '', '', $testtaskApp); + $menu .= $this->buildMenu('testtask', 'create', "product=$build->product&execution={$executionID}&build=$build->id&projectID=$build->project", $build, $type, 'bullhorn', '', '', '', $testtaskApp); if($tab == 'execution' and !empty($execution->type) and $execution->type != 'kanban') $menu .= $this->buildMenu('execution', 'bug', "execution={$extraParams['executionID']}&productID={$extraParams['productID']}&orderBy=status&build=$build->id", $build, $type, '', '', '', '', $this->lang->execution->viewBug); if($tab == 'project' or empty($execution->type) or $execution->type == 'kanban') $menu .= $this->buildMenu('build', 'view', "{$params}&type=generatedBug", $build, $type, 'bug', '', '', '', "data-app='$tab'", $this->lang->project->bug); diff --git a/module/ci/model.php b/module/ci/model.php index 5d89266128..076a2fc22c 100644 --- a/module/ci/model.php +++ b/module/ci/model.php @@ -281,6 +281,7 @@ class ciModel extends model } $this->dao->update(TABLE_MR)->data($newMR)->where('id')->eq($relateMR->id)->exec(); + $this->mr->linkObjects($relateMR); } elseif($status != 'success') { diff --git a/module/common/lang/de.php b/module/common/lang/de.php index 14e01b3443..2baf6cd3cf 100644 --- a/module/common/lang/de.php +++ b/module/common/lang/de.php @@ -353,7 +353,7 @@ $lang->setLang = 'Language Setting'; /* Theme style. */ $lang->theme = 'Theme'; -$lang->themes['default'] = 'ZenTao Blau (Standard)'; +$lang->themes['default'] = 'Standard'; $lang->themes['blue'] = 'Young Blue'; $lang->themes['green'] = 'Grün'; $lang->themes['red'] = 'Rot'; diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index 78d0cbc750..43252f5b86 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -146,7 +146,7 @@ $lang->program->menuOrder[20] = 'stakeholder'; $lang->program->menu->personnel['subMenu'] = new stdClass(); $lang->program->menu->personnel['subMenu']->invest = array('link' => "{$lang->personnel->invest}|personnel|invest|programID=%s"); $lang->program->menu->personnel['subMenu']->accessible = array('link' => "{$lang->personnel->accessible}|personnel|accessible|programID=%s"); -$lang->program->menu->personnel['subMenu']->whitelist = array('link' => "{$lang->whitelist}|personnel|whitelist|objectID=%s&module=program", 'alias' => 'addwhitelist'); +$lang->program->menu->personnel['subMenu']->whitelist = array('link' => "{$lang->whitelist}|personnel|whitelist|objectID=%s", 'alias' => 'addwhitelist'); /* Product menu. */ $lang->product->homeMenu = new stdclass(); diff --git a/module/common/model.php b/module/common/model.php index bd2c824dc7..94b8c4d0dc 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -28,6 +28,7 @@ class commonModel extends model $this->sendHeader(); $this->setCompany(); $this->setUser(); + $this->setApproval(); $this->loadConfigFromDB(); $this->app->setTimezone(); $this->loadCustomFromDB(); @@ -284,6 +285,18 @@ class commonModel extends model } } + /** + * Set approval config. + * + * @access public + * @return void + */ + public function setApproval() + { + $this->config->openedApproval = false; + if($this->config->edition == 'max' && $this->config->vision == 'rnd') $this->config->openedApproval = true; + } + /** * Load configs from database and save it to config->system and config->personal. * @@ -1667,19 +1680,19 @@ EOD; } else { - return html::a($link, "", $target, "class='btn btn-link $extraClass' title='$title' $misc", false); + return html::a($link, "", $target, "class='btn btn-link $extraClass' title=\"$title\" $misc", false); } } else { - return html::a($link, "", $target, "class='btn $extraClass' title='$title' $misc", false) . "\n"; + return html::a($link, "", $target, "class='btn $extraClass' title=\"$title\" $misc", false) . "\n"; } } else { if($type == 'list') { - return "\n"; + return "\n"; } } } @@ -1796,18 +1809,20 @@ EOD; * Print back link * * @param string $backLink + * @param string $class + * @param string $misc * @static * @access public * @return void */ - static public function printBack($backLink, $class = '') + static public function printBack($backLink, $class = '', $misc = '') { global $lang, $app; if(isonlybody()) return false; if(empty($class)) $class = 'btn'; $title = $lang->goback . $lang->backShortcutKey; - echo html::a($backLink, ' ' . $lang->goback, '', "id='back' class='{$class}' title={$title} data-app='{$app->tab}'"); + echo html::a($backLink, ' ' . $lang->goback, '', "id='back' class='{$class}' title={$title} $misc"); } /** diff --git a/module/common/view/action.html.php b/module/common/view/action.html.php index b07da8587d..24dd9fcd79 100755 --- a/module/common/view/action.html.php +++ b/module/common/view/action.html.php @@ -50,7 +50,7 @@
    - comment) != '' and $this->methodName == 'view' and $action->actor == $this->app->user->account and common::hasPriv('action', 'editComment'));?> + comment) != '' and strpos(',view,objectlibs,viewcard,', ",$this->methodName,") !== false and $action->actor == $this->app->user->account and common::hasPriv('action', 'editComment'));?>
  1. actor = zget($users, $action->actor); diff --git a/module/custom/model.php b/module/custom/model.php index 2ff04d5438..93274c6418 100644 --- a/module/custom/model.php +++ b/module/custom/model.php @@ -701,8 +701,10 @@ class customModel extends model } } + $vision = $this->config->vision; + $this->loadModel('setting'); - $this->setting->setItems("system.{$moduleName}", $requiredFields); + $this->setting->setItems("system.{$moduleName}@$vision", $requiredFields); } /** diff --git a/module/design/css/linkcommit.css b/module/design/css/linkcommit.css index d1a2a856a5..006029f60f 100644 --- a/module/design/css/linkcommit.css +++ b/module/design/css/linkcommit.css @@ -3,6 +3,7 @@ .searchBox .srearch-date{float: left; width: 20%} .searchBox h4{float:left;display: inline-block} .searchBox span{float:left;line-height:30px} +.body-modal .main-header {z-index: 5;} #logForm .table thead th{background: #efefef} #begin{margin-right:5px} #end{margin-left:5px} diff --git a/module/doc/config.php b/module/doc/config.php index 626efc5a30..45fac598de 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -21,9 +21,10 @@ $config->doc->custom->objectLibs = $config->doc->customObjectLibs; $config->doc->custom->showLibs = 'zero,children'; $config->doc->editor = new stdclass(); -$config->doc->editor->create = array('id' => 'content', 'tools' => 'fullTools'); -$config->doc->editor->edit = array('id' => 'content', 'tools' => 'fullTools'); -$config->doc->editor->view = array('id' => 'comment,lastComment', 'tools' => 'simple'); +$config->doc->editor->create = array('id' => 'content', 'tools' => 'fullTools'); +$config->doc->editor->edit = array('id' => 'content', 'tools' => 'fullTools'); +$config->doc->editor->view = array('id' => 'comment,lastComment', 'tools' => 'simple'); +$config->doc->editor->objectlibs = array('id' => 'comment,lastComment', 'tools' => 'simple'); $config->doc->markdown = new stdclass(); $config->doc->markdown->create = array('id' => 'contentMarkdown', 'tools' => 'withchange'); diff --git a/module/doc/control.php b/module/doc/control.php index d66c7ae8f4..52a5c4c5f1 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -483,6 +483,7 @@ class doc extends control $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->lib = $lib; $this->view->groups = $this->loadModel('group')->getPairs(); $this->view->users = $this->user->getPairs('noletter|noclosed|nodeleted', $doc->users); $this->display(); diff --git a/module/doc/js/common.js b/module/doc/js/common.js index 432a790f3e..be9b87367f 100644 --- a/module/doc/js/common.js +++ b/module/doc/js/common.js @@ -50,7 +50,7 @@ function toggleAcl(acl, type) var notice = typeof(noticeAcl[libType][acl]) != 'undefined' ? noticeAcl[libType][acl] : ''; $('#noticeAcl').html(notice); - if((libType == 'custom' || libType == 'api') && acl == 'private') $('#whiteListBox').addClass('hidden'); + if((libType == 'custom' || libType == 'api' || libType == 'book') && acl == 'private') $('#whiteListBox').addClass('hidden'); if(libType == 'project' && typeof(doclibID) != 'undefined') { diff --git a/module/doc/js/edit.js b/module/doc/js/edit.js index 3e71c6be4c..c5c0f24b49 100644 --- a/module/doc/js/edit.js +++ b/module/doc/js/edit.js @@ -169,7 +169,7 @@ function loadWhitelist(libID) $('#aclcustom').parent('.radio-inline').removeClass('hidden'); $('#users').replaceWith(users); - $('#user').next('.picker').remove(); + $('#users').next('.picker').remove(); $('#users').picker(); } }); diff --git a/module/doc/lang/de.php b/module/doc/lang/de.php index d63e726e2d..90e77680b5 100644 --- a/module/doc/lang/de.php +++ b/module/doc/lang/de.php @@ -48,7 +48,7 @@ $lang->doc->common = 'Dok'; $lang->doc->id = 'ID'; $lang->doc->product = $lang->productCommon; $lang->doc->project = 'Project'; -$lang->doc->execution = $lang->executionCommon; +$lang->doc->execution = $lang->execution->common; $lang->doc->lib = 'Bibliothek'; $lang->doc->module = 'Modul'; $lang->doc->object = 'Object'; @@ -161,7 +161,7 @@ $lang->doc->allProjects = 'All' . $lang->projectCommon . 's'; $lang->doc->libTypeList['product'] = $lang->productCommon . ' Bibliothek'; if($config->systemMode == 'new') $lang->doc->libTypeList['project'] = 'Project Library'; -$lang->doc->libTypeList['execution'] = $lang->executionCommon . ' Bibliothek'; +$lang->doc->libTypeList['execution'] = $lang->execution->common . ' Bibliothek'; $lang->doc->libTypeList['api'] = 'API Library'; $lang->doc->libTypeList['custom'] = 'Eigene Bibliothek'; @@ -251,8 +251,8 @@ $lang->doc->noticeAcl['lib']['project']['default'] = 'Users who can access the $lang->doc->noticeAcl['lib']['project']['open'] = 'Users who can access the selected project can access it.'; $lang->doc->noticeAcl['lib']['project']['private'] = 'Users who can access the selected project or users in the whiltelist can access it.'; $lang->doc->noticeAcl['lib']['project']['custom'] = 'Users who can access the selected project or users in the whiltelist can access it.'; -$lang->doc->noticeAcl['lib']['execution']['default'] = "Users who can access the selected {$lang->executionCommon} can access it."; -$lang->doc->noticeAcl['lib']['execution']['custom'] = "Users who can access the selected {$lang->executionCommon} or users in the whiltelist can access it."; +$lang->doc->noticeAcl['lib']['execution']['default'] = "Users who can access the selected {$lang->execution->common} can access it."; +$lang->doc->noticeAcl['lib']['execution']['custom'] = "Users who can access the selected {$lang->execution->common} or users in the whiltelist can access it."; $lang->doc->noticeAcl['lib']['api']['open'] = 'All users can access it.'; $lang->doc->noticeAcl['lib']['api']['custom'] = 'Users in the whitelist can access it.'; $lang->doc->noticeAcl['lib']['api']['private'] = 'Only the one who created it can access it.'; diff --git a/module/doc/lang/en.php b/module/doc/lang/en.php index d3e052be03..22ffeedc54 100644 --- a/module/doc/lang/en.php +++ b/module/doc/lang/en.php @@ -251,8 +251,8 @@ $lang->doc->noticeAcl['lib']['project']['default'] = 'Users who can access the $lang->doc->noticeAcl['lib']['project']['open'] = 'Users who can access the selected project can access it.'; $lang->doc->noticeAcl['lib']['project']['private'] = 'Users who can access the selected project or users in the whiltelist can access it.'; $lang->doc->noticeAcl['lib']['project']['custom'] = 'Users in the whiltelist can access it.'; -$lang->doc->noticeAcl['lib']['execution']['default'] = "Users who can access the selected {$lang->executionCommon} can access it."; -$lang->doc->noticeAcl['lib']['execution']['custom'] = "Users who can access the selected {$lang->executionCommon} or users in the whiltelist can access it."; +$lang->doc->noticeAcl['lib']['execution']['default'] = "Users who can access the selected {$lang->execution->common} can access it."; +$lang->doc->noticeAcl['lib']['execution']['custom'] = "Users who can access the selected {$lang->execution->common} or users in the whiltelist can access it."; $lang->doc->noticeAcl['lib']['api']['open'] = 'All users can access it.'; $lang->doc->noticeAcl['lib']['api']['custom'] = 'Users in the whitelist can access it.'; $lang->doc->noticeAcl['lib']['api']['private'] = 'Only the one who created it can access it.'; diff --git a/module/doc/lang/fr.php b/module/doc/lang/fr.php index b9379ba42a..e7f59b7b84 100644 --- a/module/doc/lang/fr.php +++ b/module/doc/lang/fr.php @@ -48,7 +48,7 @@ $lang->doc->common = 'Gestion Documentaire'; $lang->doc->id = 'ID'; $lang->doc->product = $lang->productCommon; $lang->doc->project = 'Project'; -$lang->doc->execution = $lang->executionCommon; +$lang->doc->execution = $lang->execution->common; $lang->doc->lib = 'Bibliothèque'; $lang->doc->module = 'Catégorie'; $lang->doc->object = 'Object'; @@ -161,7 +161,7 @@ $lang->doc->allProjects = 'All' . $lang->projectCommon . 's'; $lang->doc->libTypeList['product'] = $lang->productCommon . ' Library'; if($config->systemMode == 'new') $lang->doc->libTypeList['project'] = 'Project Library'; -$lang->doc->libTypeList['execution'] = 'Bibliothèque ' . $lang->executionCommon; +$lang->doc->libTypeList['execution'] = 'Bibliothèque ' . $lang->execution->common; $lang->doc->libTypeList['api'] = 'API Library'; $lang->doc->libTypeList['custom'] = 'Bib. Personnalisée'; @@ -251,8 +251,8 @@ $lang->doc->noticeAcl['lib']['project']['default'] = 'Les utilisateurs qui ont $lang->doc->noticeAcl['lib']['project']['open'] = 'Users who can access the selected project can access it.'; $lang->doc->noticeAcl['lib']['project']['private'] = 'Users who can access the selected project or users in the whiltelist can access it.'; $lang->doc->noticeAcl['lib']['project']['custom'] = 'Les utilisateurs qui ont accès au Projet ou les utilisateurs de la Liste Blanche peuvent y accéder.'; -$lang->doc->noticeAcl['lib']['execution']['default'] = "Les utilisateurs qui ont accès au {$lang->executionCommon} peuvent y accéder."; -$lang->doc->noticeAcl['lib']['execution']['custom'] = "Les utilisateurs qui ont accès au {$lang->executionCommon} ou les utilisateurs de la Liste Blanche peuvent y accéder."; +$lang->doc->noticeAcl['lib']['execution']['default'] = "Les utilisateurs qui ont accès au {$lang->execution->common} peuvent y accéder."; +$lang->doc->noticeAcl['lib']['execution']['custom'] = "Les utilisateurs qui ont accès au {$lang->execution->common} ou les utilisateurs de la Liste Blanche peuvent y accéder."; $lang->doc->noticeAcl['lib']['api']['open'] = 'All users can access it.'; $lang->doc->noticeAcl['lib']['api']['custom'] = 'Users in the whitelist can access it.'; $lang->doc->noticeAcl['lib']['api']['private'] = 'Only the one who created it can access it.'; diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php index ddbd9cea78..c42abbd0c2 100644 --- a/module/doc/lang/zh-cn.php +++ b/module/doc/lang/zh-cn.php @@ -251,8 +251,8 @@ $lang->doc->noticeAcl['lib']['project']['default'] = "有所选项目访问权 $lang->doc->noticeAcl['lib']['project']['open'] = "有所选项目访问权限的用户可以访问。"; $lang->doc->noticeAcl['lib']['project']['private'] = "有所选项目访问权限或白名单里的用户可以访问。"; $lang->doc->noticeAcl['lib']['project']['custom'] = "白名单的用户可以访问。"; -$lang->doc->noticeAcl['lib']['execution']['default'] = "有所选{$lang->executionCommon}访问权限的用户可以访问。"; -$lang->doc->noticeAcl['lib']['execution']['custom'] = "有所选{$lang->executionCommon}访问权限或白名单里的用户可以访问。"; +$lang->doc->noticeAcl['lib']['execution']['default'] = "有所选{$lang->execution->common}访问权限的用户可以访问。"; +$lang->doc->noticeAcl['lib']['execution']['custom'] = "有所选{$lang->execution->common}访问权限或白名单里的用户可以访问。"; $lang->doc->noticeAcl['lib']['api']['open'] = '所有人都可以访问。'; $lang->doc->noticeAcl['lib']['api']['custom'] = '白名单的用户可以访问。'; $lang->doc->noticeAcl['lib']['api']['private'] = '只有创建者自己可以访问。'; diff --git a/module/doc/view/edit.html.php b/module/doc/view/edit.html.php index 9a092fe015..3569041e5c 100644 --- a/module/doc/view/edit.html.php +++ b/module/doc/view/edit.html.php @@ -83,8 +83,9 @@ doclib->control;?> - doc->aclList, $doc->acl, "onchange='toggleAcl(this.value, \"doc\")'")?> - doc->noticeAcl['doc'][$doc->acl];?> + acl == 'private' ? 'private' : $doc->acl;?> + doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'")?> + doc->noticeAcl['doc'][$acl];?> diff --git a/module/doc/view/objectlibs.html.php b/module/doc/view/objectlibs.html.php index cd6df9b47c..26478698e9 100644 --- a/module/doc/view/objectlibs.html.php +++ b/module/doc/view/objectlibs.html.php @@ -11,6 +11,7 @@ */ ?> + tab == 'execution'):;?> diff --git a/module/execution/control.php b/module/execution/control.php index 8f334c11d6..b509ca3f4f 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -984,6 +984,9 @@ class execution extends control $showModule = !empty($this->config->datatable->bugBrowse->showModule) ? $this->config->datatable->bugBrowse->showModule : ''; + /* Process the openedBuild and resolvedBuild fields. */ + $bugs = $this->bug->processBuildForBugs($bugs); + /* Assign. */ $this->view->title = $title; $this->view->position = $position; diff --git a/module/execution/lang/de.php b/module/execution/lang/de.php index c39f1544ad..0441cf1ed8 100644 --- a/module/execution/lang/de.php +++ b/module/execution/lang/de.php @@ -380,8 +380,8 @@ $lang->execution->errorBegin = "The start time of {$lang->execu $lang->execution->errorEnd = "The end time of {$lang->executionCommon} cannot be greater than the end time %s of the project."; $lang->execution->errorLetterProject = "The start time of stage cannot be less than the start time of the project %s."; $lang->execution->errorGreaterProject = "The end time of stage cannot be greater than the end time %s of the project."; -$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' "%s" should be ≥ the start date of project %s: %s.'; -$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' "%s" should be ≤ the deadline of project %s: %s.'; +$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' should be ≥ the start date of project : %s.'; +$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.'; $lang->execution->accessDenied = "Zugriff zu {$lang->executionCommon} verweigert!"; $lang->execution->tips = 'Hinweis'; $lang->execution->afterInfo = "{$lang->executionCommon} wurde erstellt. Als nächstes können Sie "; diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index 242f35f23b..3d1edaddc3 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -380,8 +380,8 @@ $lang->execution->errorBegin = "The start time of {$lang->execu $lang->execution->errorEnd = "The end time of {$lang->executionCommon} cannot be greater than the end time %s of the project."; $lang->execution->errorLetterProject = "The start time of stage cannot be less than the start time of the project %s."; $lang->execution->errorGreaterProject = "The end time of stage cannot be greater than the end time %s of the project."; -$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' "%s" should be ≥ the start date of project "%s": %s.'; -$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' "%s" should be ≤ the deadline of project "%s": %s.'; +$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' should be ≥ the start date of project : %s.'; +$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.'; $lang->execution->accessDenied = "Your access to {$lang->executionCommon} is denied!"; $lang->execution->tips = 'Note'; $lang->execution->afterInfo = "{$lang->executionCommon} is created. Next you can "; diff --git a/module/execution/lang/fr.php b/module/execution/lang/fr.php index 2c882fcda4..ff687861fd 100644 --- a/module/execution/lang/fr.php +++ b/module/execution/lang/fr.php @@ -284,16 +284,19 @@ $lang->execution->taskKanban = 'Task Kanban'; $lang->execution->RDKanban = 'Research & Development Kanban'; /* Group browsing. */ -$lang->execution->allTasks = 'Voir Toutes'; +$lang->execution->allTasks = 'Toutes'; $lang->execution->assignedToMe = 'à Moi'; -$lang->execution->myInvolved = "Où j'ai participé"; -$lang->execution->assignedByMe = 'AssignedByMe'; +$lang->execution->myInvolved = "Ma part"; +$lang->execution->assignedByMe = 'Assignée par moi'; $lang->execution->statusSelects[''] = 'Plus...'; $lang->execution->statusSelects['wait'] = 'En Attente'; $lang->execution->statusSelects['doing'] = 'En Cours'; $lang->execution->statusSelects['undone'] = 'Non terminées'; +$lang->execution->statusSelects['myinvolved'] = $lang->execution->myInvolved; $lang->execution->statusSelects['finishedbyme'] = 'Terminées par moi'; +$lang->execution->statusSelects['assignedbyme'] = $lang->execution->assignedByMe; +$lang->execution->statusSelects['needconfirm'] = 'A confirmer'; $lang->execution->statusSelects['done'] = 'Faites'; $lang->execution->statusSelects['closed'] = 'Fermées'; $lang->execution->statusSelects['cancel'] = 'Annulées'; @@ -380,8 +383,8 @@ $lang->execution->errorBegin = "The start time of {$lang->execu $lang->execution->errorEnd = "The end time of {$lang->executionCommon} cannot be greater than the end time %s of the project."; $lang->execution->errorLetterProject = "The start time of stage cannot be less than the start time of the project %s."; $lang->execution->errorGreaterProject = "The end time of stage cannot be greater than the end time %s of the project."; -$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' "%s" should be ≥ the start date of project %s: %s.'; -$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' "%s" should be ≤ the deadline of project %s: %s.'; +$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' should be ≥ the start date of project : %s.'; +$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.'; $lang->execution->accessDenied = "Votre accès au {$lang->executionCommon} est refusé ! Désolé."; $lang->execution->tips = 'Note'; $lang->execution->afterInfo = "Le {$lang->executionCommon} a été créé avec succès ! Ensuite vous pouvez "; @@ -476,9 +479,6 @@ $lang->execution->typeList['kanban'] = 'Kanban'; $lang->execution->featureBar['task']['all'] = $lang->execution->allTasks; $lang->execution->featureBar['task']['unclosed'] = $lang->execution->unclosed; $lang->execution->featureBar['task']['assignedtome'] = $lang->execution->assignedToMe; -$lang->execution->featureBar['task']['myinvolved'] = $lang->execution->myInvolved; -$lang->execution->featureBar['task']['assignedbyme'] = $lang->execution->assignedByMe; -$lang->execution->featureBar['task']['needconfirm'] = 'A confirmer'; $lang->execution->featureBar['task']['status'] = $lang->execution->statusSelects['']; $lang->execution->featureBar['all']['all'] = $lang->execution->all; diff --git a/module/execution/lang/vi.php b/module/execution/lang/vi.php index 766a66f77f..c1f02f6280 100644 --- a/module/execution/lang/vi.php +++ b/module/execution/lang/vi.php @@ -337,6 +337,8 @@ $lang->execution->unfinishedExecution = "This {$lang->executionCommon} h $lang->execution->unfinishedTask = "[%s] unfinished tasks. "; $lang->execution->unresolvedBug = "[%s] unresolved bugs. "; $lang->execution->projectNotEmpty = 'Project cannot be empty.'; +$lang->execution->errorCommonBegin = 'The start date of ' . $lang->executionCommon . ' should be ≥ the start date of project : %s.'; +$lang->execution->errorCommonEnd = 'The deadline of ' . $lang->executionCommon . ' should be ≤ the deadline of project : %s.'; /* Statistics. */ $lang->execution->charts = new stdclass(); diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index b29446e64e..eb4a3b6bd7 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -380,8 +380,8 @@ $lang->execution->errorBegin = "{$lang->executionCommon}的开 $lang->execution->errorEnd = "{$lang->executionCommon}的截止时间不能大于所属项目的结束时间%s。"; $lang->execution->errorLetterProject = "阶段的计划开始时间不能小于所属项目的计划开始时间%s。"; $lang->execution->errorGreaterProject = "阶段的计划完成时间不能大于所属项目的计划完成时间%s。"; -$lang->execution->errorCommonBegin = $lang->executionCommon . '“%s”开始日期应大于等于项目“%s”的开始日期:%s。'; -$lang->execution->errorCommonEnd = $lang->executionCommon . '“%s”截止日期应小于等于项目“%s”的截止日期:%s。'; +$lang->execution->errorCommonBegin = $lang->executionCommon . '开始日期应大于等于项目的开始日期:%s。'; +$lang->execution->errorCommonEnd = $lang->executionCommon . '截止日期应小于等于项目的截止日期:%s。'; $lang->execution->accessDenied = "您无权访问该{$lang->executionCommon}!"; $lang->execution->tips = '提示'; $lang->execution->afterInfo = "{$lang->executionCommon}添加成功,您现在可以进行以下操作:"; diff --git a/module/execution/model.php b/module/execution/model.php index bcfe9f25f4..124dd02c13 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -305,7 +305,7 @@ class executionModel extends model return false; } - if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($_POST['project'], $_POST['begin'], $_POST['end'], $_POST['name']); + if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($_POST['project'], $_POST['begin'], $_POST['end']); if(dao::isError()) return false; /* Determine whether to add a sprint or a stage according to the model of the execution. */ @@ -500,7 +500,7 @@ class executionModel extends model if(in_array($execution->status, array('closed', 'suspended'))) $this->computeBurn($executionID); - if($this->config->systemMode == 'new' and (empty($execution->project) or $execution->project == $oldExecution->project)) $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end, $execution->name); + if($this->config->systemMode == 'new' and (empty($execution->project) or $execution->project == $oldExecution->project)) $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end); if(dao::isError()) return false; /* Child stage inherits parent stage permissions. */ @@ -869,7 +869,7 @@ class executionModel extends model ->remove('comment') ->get(); - if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end, $oldExecution->name); + if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end); if(dao::isError()) return false; $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->putoff['id'], $this->post->uid); @@ -1117,16 +1117,15 @@ class executionModel extends model * @param int $projectID * @param string $begin * @param string $end - * @param string $executionName * @access public * @return void */ - public function checkBeginAndEndDate($projectID, $begin, $end, $executionName) + public function checkBeginAndEndDate($projectID, $begin, $end) { $project = $this->loadModel('project')->getByID($projectID); - if($begin < $project->begin) dao::$errors['begin'] = sprintf($this->lang->execution->errorCommonBegin, $executionName, $project->name, $project->begin); - if($end > $project->end) dao::$errors['end'] = sprintf($this->lang->execution->errorCommonEnd, $executionName, $project->name, $project->end); + if($begin < $project->begin) dao::$errors['begin'] = sprintf($this->lang->execution->errorCommonBegin, $project->begin); + if($end > $project->end) dao::$errors['end'] = sprintf($this->lang->execution->errorCommonEnd, $project->end); } /* diff --git a/module/execution/view/treetask.html.php b/module/execution/view/treetask.html.php index 93ad75b280..388aa093bf 100644 --- a/module/execution/view/treetask.html.php +++ b/module/execution/view/treetask.html.php @@ -3,7 +3,7 @@

    id?> status}";?>">processStatus('task', $task);?> - + parent > 0) echo '' . $this->lang->task->childrenAB . '';?> team)) echo '' . $this->lang->task->multipleAB . '';?> parentName) ? $task->parentName . '/' : '';?>name;?> diff --git a/module/index/css/index.css b/module/index/css/index.css index 185b6fb9cc..39a1f80603 100644 --- a/module/index/css/index.css +++ b/module/index/css/index.css @@ -49,7 +49,7 @@ body.menu-hide {padding-left: 0;} .app-container {position: absolute; left: 0; bottom: 40px; right: 0; top: 0; background-color: #efefef;} .menu-hide #apps {left: 40px;} .app-container.loading:before {background-color: rgba(0,0,0,.1);} -.app-container.loading:before, .app-container.loading::after {transition-delay: 1s;} +.app-container.loading:before, .app-container.loading::after {transition-delay: 3s;} #appsBar {position: fixed; left: 96px; bottom: 0; right: 0; height: 40px; z-index: 1012; background: #fff; border-top: 1px solid #eff1f7;} .menu-hide #appsBar {left: 40px;} diff --git a/module/index/css/index.en.css b/module/index/css/index.en.css index ac1227a07e..c008c4a5df 100644 --- a/module/index/css/index.en.css +++ b/module/index/css/index.en.css @@ -1 +1,2 @@ +#apps { left: 106px;} #menu { width: 106px;} diff --git a/module/index/js/index.js b/module/index/js/index.js index 3ae31f534a..d924d87bf8 100644 --- a/module/index/js/index.js +++ b/module/index/js/index.js @@ -463,7 +463,7 @@ { app.$app.removeClass('loading'); app._loadTimer = null; - }, 10000); + }, 15000); } /** diff --git a/module/kanban/config.php b/module/kanban/config.php index fc6374a1ff..27373d5b3f 100644 --- a/module/kanban/config.php +++ b/module/kanban/config.php @@ -40,7 +40,7 @@ $config->kanban->editor->createcard = array('id' => 'desc', 'tools' => 'simpl $config->kanban->editor->activate = array('id' => 'comment', 'tools' => 'simpleTools'); $config->kanban->editor->close = array('id' => 'comment', 'tools' => 'simpleTools'); $config->kanban->editor->editcard = array('id' => 'desc', 'tools' => 'simpleTools'); -$config->kanban->editor->viewcard = array('id' => 'comment', 'tools' => 'simpleTools'); +$config->kanban->editor->viewcard = array('id' => 'comment,lastComment', 'tools' => 'simpleTools'); $config->kanban->editor->activatecard = array('id' => 'comment', 'tools' => 'simpleTools'); $config->kanban->fromType = array('execution', 'productplan', 'release', 'build'); diff --git a/module/kanban/control.php b/module/kanban/control.php index 6eb6747023..40f8c8d49c 100644 --- a/module/kanban/control.php +++ b/module/kanban/control.php @@ -1433,8 +1433,7 @@ class kanban extends control if(isonlybody()) return print(js::reload('parent.parent')); - $card = $this->kanban->getCardByID($cardID); - $kanbanGroup = $this->kanban->getKanbanData($card->kanban, $card->region); + $kanbanGroup = $this->kanban->getKanbanData($card->kanban, $card->region); $kanbanGroupParam = json_encode($kanbanGroup); return print(""); } diff --git a/module/kanban/css/editspace.css b/module/kanban/css/editspace.css index 47dd3f8470..6496806503 100644 --- a/module/kanban/css/editspace.css +++ b/module/kanban/css/editspace.css @@ -1,3 +1,4 @@ #mainContent {padding-left: 0px; height: 500px;} #contactListMenu_chosen {vertical-align: unset;} #teamBox .input-group .input-group-btn {vertical-align: top;} +.chosen-container .chosen-results {max-height: 200px;} diff --git a/module/kanban/model.php b/module/kanban/model.php index 6d7d1b2b8c..9ee506694f 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1479,6 +1479,19 @@ class kanbanModel extends model if($browseType == 'bug') $cardList = $this->loadModel('bug')->getExecutionBugs($executionID); if($browseType == 'task') $cardList = $this->loadModel('execution')->getKanbanTasks($executionID, "id"); + if($browseType == 'task' and $groupBy == 'assignedTo') + { + foreach($cardList as $id => $task) + { + if($task->mode == 'multi') + { + $task->team = $this->dao->select('t1.account,t2.realname')->from(TABLE_TEAM)->alias('t1') + ->leftJoin(TABLE_USER)->alias('t2')->on('t1.account = t2.account') + ->where('t1.root')->eq($id)->andWhere('t1.type')->eq('task')->orderBy('t1.order')->fetchPairs('account'); + } + } + } + /* Get objects cards menus. */ if($browseType == 'story') $storyCardMenu = $this->getKanbanCardMenu($executionID, $cardList, 'story'); if($browseType == 'bug') $bugCardMenu = $this->getKanbanCardMenu($executionID, $cardList, 'bug'); @@ -1564,7 +1577,12 @@ class kanbanModel extends model $cardData = array(); if(in_array($groupBy, array('module', 'story', 'pri', 'severity')) and (int)$object->$groupBy !== $laneID) continue; - if(in_array($groupBy, array('assignedTo', 'type', 'category', 'source')) and $object->$groupBy !== $laneID) continue; + if(in_array($groupBy, array('type', 'category', 'source')) and $object->$groupBy !== $laneID) continue; + if($groupBy == 'assignedTo') + { + if(empty($object->team) and $object->$groupBy !== $laneID) continue; + if(!empty($object->team) and !in_array($laneID, array_keys($object->team), true)) continue; + } $cardData['id'] = $object->id; $cardData['order'] = $cardOrder; @@ -1625,6 +1643,14 @@ class kanbanModel extends model foreach($cardList as $item) { if(!isset($groupByList[$item->$groupBy])) $groupByList[$item->$groupBy] = $item->$groupBy; + + if($groupBy == 'assignedTo' and !empty($item->team)) + { + foreach($item->team as $account => $name) + { + if(!isset($groupByList[$account])) $groupByList[$account] = $account; + } + } } if(in_array($groupBy, array('module', 'story', 'assignedTo'))) diff --git a/module/my/view/testcase.html.php b/module/my/view/testcase.html.php index 2d87456686..6a3bb26041 100644 --- a/module/my/view/testcase.html.php +++ b/module/my/view/testcase.html.php @@ -108,8 +108,8 @@ $disabled = $case->status == 'wait' ? 'disabled' : ''; common::printIcon('testcase', 'createBug', "product=$case->product&branch=$case->branch&extra=caseID=$caseID,version=$case->version,runID=$runID", $case, 'list', 'bug', '', 'iframe', 'true', "data-app='qa' data-toggle=''"); common::printIcon('testcase', 'create', "productID=$case->product&branch=$case->branch&moduleID=$case->module&from={$app->rawMethod}¶m=$caseID", $case, 'list', 'copy', '', 'iframe', true, "data-width='95%'"); - common::printIcon('testtask', 'runCase', "runID=$runID&caseID=$caseID&version=$case->version", '', 'list', 'play', '', "iframe $disabled", true, "data-width='95%'", '', $case->project); - common::printIcon('testtask', 'results', "runID=$runID&caseID=$caseID", '', 'list', 'list-alt', '', 'iframe', true, "data-width='95%'", '', $case->project); + common::printIcon('testtask', 'runCase', "runID=0&caseID=$caseID&version=$case->version", '', 'list', 'play', '', "iframe $disabled", true, "data-width='95%'", '', $case->project); + common::printIcon('testtask', 'results', "runID=0&caseID=$caseID", '', 'list', 'list-alt', '', 'iframe', true, "data-width='95%'", '', $case->project); common::printIcon('testcase', 'edit', "caseID=$caseID", $case, 'list', 'edit', '', 'iframe', true, "data-width='95%'", '', $case->project); } ?> diff --git a/module/personnel/view/whitelist.html.php b/module/personnel/view/whitelist.html.php index ad1d4346df..65ec18427c 100644 --- a/module/personnel/view/whitelist.html.php +++ b/module/personnel/view/whitelist.html.php @@ -58,6 +58,7 @@ email;?> app->tab == 'program') $module = 'program'; if(common::hasPriv($module, 'unbindWhitelist')) echo html::a($this->createLink($module, 'unbindWhitelist', "id=$user->id&confirm=no"), '', 'hiddenwin', "title='{$lang->personnel->delete}' class='btn' $tab"); ?> diff --git a/module/product/control.php b/module/product/control.php index 4f724735e9..1108ea3e27 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -148,18 +148,18 @@ class product extends control } /* Set menu. */ - if($this->app->tab == 'product') + if($this->app->tab == 'project') + { + $this->session->set('storyList', $this->app->getURI(true), 'project'); + $this->loadModel('project')->setMenu($projectID); + } + else { $this->session->set('storyList', $this->app->getURI(true), 'product'); $this->session->set('productList', $this->app->getURI(true), 'product'); $this->product->setMenu($productID, $branch, 0, '', "storyType=$storyType"); } - if($this->app->tab == 'project') - { - $this->session->set('storyList', $this->app->getURI(true), 'project'); - $this->loadModel('project')->setMenu($projectID); - } /* Lower browse type. */ $browseType = strtolower($browseType); diff --git a/module/product/js/all.js b/module/product/js/all.js index e3e8a72217..9d18908c92 100644 --- a/module/product/js/all.js +++ b/module/product/js/all.js @@ -60,12 +60,19 @@ $(function() }); } - /* Add a statistics prompt statement after the Edit button */ + /** + * Add a statistics prompt statement after the Edit button. + * + * @access public + * @return void + */ function addStatistic() { var checkedLength = $(":checkbox[name^='productIDList']:checked").length; var summary = checkedProducts.replace('%s', checkedLength); + if(cilentLang == "en" && checkedLength < 2) summary = summary.replace('products', 'product'); var statistic = "
    " + summary + "
    "; + if(checkedLength > 0) { $('#productsSummary').remove(); @@ -77,6 +84,35 @@ $(function() } } + /** + * Anti shake operation for jquery. + * + * @param fn $fn + * @param delay $delay + * @access public + * @return void + */ + function debounce(fn, delay) + { + var timer = null; + return function() + { + if(timer) clearTimeout(timer); + timer = setTimeout(fn, delay) + } + } + + /** + * Update statistics. + * + * @access public + * @return void + */ + function updateStatistic() + { + debounce(addStatistic(), 200) + } + $('#productTableList').on('click', '.row-program,.row-line', function(e) { if($(e.target).closest('.table-nest-toggle,a').length) return; @@ -96,7 +132,7 @@ $(function() { updatePrarentCheckbox($('#productTableList>tr[data-id="' + parentID + '"]')); } - addStatistic() + updateStatistic() }); $('#productListForm').on('checkChange', updateCheckboxes); @@ -104,7 +140,7 @@ $(function() $(":checkbox[name^='productIDList']").on('click', function() { - addStatistic() + updateStatistic() }); $(".check-all").on('click', function() @@ -117,6 +153,6 @@ $(function() { $(":checkbox[name^='productIDList']").prop('checked', true); } - addStatistic() + updateStatistic() }); }); diff --git a/module/product/lang/en.php b/module/product/lang/en.php index 5c30a03101..ec8f1e6c14 100644 --- a/module/product/lang/en.php +++ b/module/product/lang/en.php @@ -207,8 +207,6 @@ $lang->product->noMatched = '"%s" cannot be found.' . $lang->productCommon; $lang->product->featureBar['browse']['allstory'] = $lang->product->allStory; $lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed; $lang->product->featureBar['browse']['assignedtome'] = $lang->product->assignedToMe; -$lang->product->featureBar['browse']['openedbyme'] = $lang->product->openedByMe; -$lang->product->featureBar['browse']['reviewedbyme'] = $lang->product->reviewedByMe; $lang->product->featureBar['browse']['reviewbyme'] = $lang->product->reviewByMe; $lang->product->featureBar['browse']['draftstory'] = $lang->product->draftStory; $lang->product->featureBar['browse']['more'] = $lang->more; @@ -217,7 +215,9 @@ $lang->product->featureBar['all']['all'] = $lang->product->allProduct; $lang->product->featureBar['all']['noclosed'] = $lang->product->unclosed; $lang->product->featureBar['all']['closed'] = $lang->product->statusList['closed']; +$lang->product->moreSelects['openedbyme'] = $lang->product->openedByMe; $lang->product->moreSelects['assignedbyme'] = $lang->product->assignedByMe; +$lang->product->moreSelects['reviewedbyme'] = $lang->product->reviewedByMe; $lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe; $lang->product->moreSelects['activestory'] = $lang->product->activeStory; $lang->product->moreSelects['changedstory'] = $lang->product->changedStory; diff --git a/module/product/view/all.html.php b/module/product/view/all.html.php index 55ff1f0cf0..0ac5a3c677 100644 --- a/module/product/view/all.html.php +++ b/module/product/view/all.html.php @@ -256,6 +256,7 @@ product->checkedProducts);?> +app->getClientLang());?> diff --git a/module/programplan/control.php b/module/programplan/control.php index fc503a4e7c..f55a7890cf 100644 --- a/module/programplan/control.php +++ b/module/programplan/control.php @@ -186,6 +186,11 @@ class programplan extends control $this->app->loadLang('project'); $this->app->loadLang('execution'); $plan = $this->programplan->getByID($planID); + + global $lang; + $lang->executionCommon = $lang->execution->stage; + include $this->app->getModulePath('', 'execution') . 'lang/' . $this->app->getClientLang() . '.php'; + if($_POST) { $changes = $this->programplan->update($planID, $projectID); diff --git a/module/programplan/model.php b/module/programplan/model.php index b0a2e30ed7..efb5b8c6ea 100755 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -735,6 +735,10 @@ class programplanModel extends model /* Judgment of required items. */ if($plan->begin == '0000-00-00') dao::$errors['begin'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->begin); if($plan->end == '0000-00-00') dao::$errors['end'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->end); + if(dao::isError()) return false; + + if($projectID) $this->loadModel('execution')->checkBeginAndEndDate($projectID, $plan->begin, $plan->end); + if(dao::isError()) return false; $planChanged = ($oldPlan->name != $plan->name || $oldPlan->milestone != $plan->milestone || $oldPlan->begin != $plan->begin || $oldPlan->end != $plan->end); diff --git a/module/project/config.php b/module/project/config.php index 21224eac94..e86ae4721a 100644 --- a/module/project/config.php +++ b/module/project/config.php @@ -73,13 +73,13 @@ $config->project->datatable->fieldList['status']['pri'] = '2'; $config->project->datatable->fieldList['begin']['title'] = 'begin'; $config->project->datatable->fieldList['begin']['fixed'] = 'no'; -$config->project->datatable->fieldList['begin']['width'] = '90'; +$config->project->datatable->fieldList['begin']['width'] = '115'; $config->project->datatable->fieldList['begin']['required'] = 'no'; $config->project->datatable->fieldList['begin']['pri'] = '9'; $config->project->datatable->fieldList['end']['title'] = 'end'; $config->project->datatable->fieldList['end']['fixed'] = 'no'; -$config->project->datatable->fieldList['end']['width'] = '90'; +$config->project->datatable->fieldList['end']['width'] = '100'; $config->project->datatable->fieldList['end']['required'] = 'no'; $config->project->datatable->fieldList['end']['pri'] = '3'; diff --git a/module/project/lang/de.php b/module/project/lang/de.php index f9a6cf60a2..0297e0c2a6 100644 --- a/module/project/lang/de.php +++ b/module/project/lang/de.php @@ -65,7 +65,7 @@ $lang->project->budgetGe0 = '『Budget』must be greater than or equal $lang->project->allProjects = 'All Projects'; /* Fields. */ -$lang->project->common = 'Program'; +$lang->project->common = 'Project'; $lang->project->id = 'ID'; $lang->project->project = 'Project'; $lang->project->stage = 'Stage'; @@ -307,21 +307,23 @@ $lang->project->programTitle['0'] = 'Hide'; $lang->project->programTitle['base'] = 'Base-level project only'; $lang->project->programTitle['end'] = 'End-level project only'; -$lang->project->accessDenied = 'Access denied!'; -$lang->project->chooseProgramType = 'Select the project management model'; -$lang->project->cannotCreateChild = 'It is not empty, so you cannot add a child. You can add a parent for it, and then create a child.'; -$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.'; -$lang->project->confirmDelete = "Do you want to delete [%s]?"; -$lang->project->cannotChangeToCat = "It is not empty, so you cannot change it to a parent."; -$lang->project->cannotCancelCat = "It has child projects, so you cannot unmark the parent."; -$lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s"; -$lang->project->parentBudget = "The budget of the parent project: "; -$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project."; -$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project."; -$lang->project->beginGreateChild = 'The start date of the project "%s" should be ≥ the start date of program "%s": %s.'; -$lang->project->endLetterChild = 'The finish date of the project "%s" should be ≤ the finish date of program "%s": %s.'; -$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too."; -$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?"; +$lang->project->accessDenied = 'Access denied!'; +$lang->project->chooseProgramType = 'Select the project management model'; +$lang->project->cannotCreateChild = 'It is not empty, so you cannot add a child. You can add a parent for it, and then create a child.'; +$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.'; +$lang->project->confirmDelete = "Do you want to delete [%s]?"; +$lang->project->cannotChangeToCat = "It is not empty, so you cannot change it to a parent."; +$lang->project->cannotCancelCat = "It has child projects, so you cannot unmark the parent."; +$lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s"; +$lang->project->parentBudget = "The budget of the parent project: "; +$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project."; +$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project."; +$lang->project->beginGreateChild = 'The start date of the project should be ≥ the start date of program: %s.'; +$lang->project->endLetterChild = 'The finish date of the project should be ≤ the finish date of program: %s.'; +$lang->project->begigLetterExecution = 'The start date of project should be ≤ the minimum start date of the execution: %s.'; +$lang->project->endGreateExecution = 'The finish date of the project should be ≥ the maximum finish date of the execution: %s.'; +$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too."; +$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?"; $lang->project->action = new stdclass(); $lang->project->action->managed = '$date, managed by $actor. $extra' . "\n"; diff --git a/module/project/lang/en.php b/module/project/lang/en.php index 3e07049109..87a656b975 100644 --- a/module/project/lang/en.php +++ b/module/project/lang/en.php @@ -318,8 +318,10 @@ $lang->project->parentBeginEnd = "The begin and end date of the parent proj $lang->project->parentBudget = "The budget of the parent project: "; $lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project."; $lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project."; -$lang->project->beginGreateChild = 'The start date of the project "%s" should be ≥ the start date of program "%s": %s.'; -$lang->project->endLetterChild = 'The finish date of the project "%s" should be ≤ the finish date of program "%s": %s.'; +$lang->project->beginGreateChild = 'The start date of the project should be ≥ the start date of program: %s.'; +$lang->project->endLetterChild = 'The finish date of the project should be ≤ the finish date of program: %s.'; +$lang->project->begigLetterExecution = 'The start date of project should be ≤ the minimum start date of the execution: %s.'; +$lang->project->endGreateExecution = 'The finish date of the project should be ≥ the maximum finish date of the execution: %s.'; $lang->project->childLongTime = "There are long-term projects in the child project, and the parent project should also be a long-term project."; $lang->project->confirmUnlinkMember = "Do you want to remove this user from project?"; diff --git a/module/project/lang/fr.php b/module/project/lang/fr.php index f3969c0654..b08f7cae8c 100644 --- a/module/project/lang/fr.php +++ b/module/project/lang/fr.php @@ -65,7 +65,7 @@ $lang->project->budgetGe0 = '『Budget』must be greater than or equal $lang->project->allProjects = 'All Projects'; /* Fields. */ -$lang->project->common = 'Project'; +$lang->project->common = 'Projets'; $lang->project->id = 'ID'; $lang->project->project = 'Project'; $lang->project->stage = 'Stage'; @@ -307,21 +307,23 @@ $lang->project->programTitle['0'] = 'Hide'; $lang->project->programTitle['base'] = 'Base-level project only'; $lang->project->programTitle['end'] = 'End-level project only'; -$lang->project->accessDenied = 'Access denied!'; -$lang->project->chooseProgramType = 'Select the project management model'; -$lang->project->cannotCreateChild = 'It is not empty, so you cannot add a child. You can add a parent for it, and then create a child.'; -$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.'; -$lang->project->confirmDelete = "Do you want to delete [%s]?"; -$lang->project->cannotChangeToCat = "It is not empty, so you cannot change it to a parent."; -$lang->project->cannotCancelCat = "It has child projects, so you cannot unmark the parent."; -$lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s"; -$lang->project->parentBudget = "The budget of the parent project: "; -$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project."; -$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project."; -$lang->project->beginGreateChild = 'La date de début du projets "%s" doit être ≥ à la date de début du programme "%s" : %s.'; -$lang->project->endLetterChild = 'La date de fin du projets "%s" doit être ≤ à la date de fin du programme "%s" : %s.'; -$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too."; -$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?"; +$lang->project->accessDenied = 'Access denied!'; +$lang->project->chooseProgramType = 'Select the project management model'; +$lang->project->cannotCreateChild = 'It is not empty, so you cannot add a child. You can add a parent for it, and then create a child.'; +$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.'; +$lang->project->confirmDelete = "Do you want to delete [%s]?"; +$lang->project->cannotChangeToCat = "It is not empty, so you cannot change it to a parent."; +$lang->project->cannotCancelCat = "It has child projects, so you cannot unmark the parent."; +$lang->project->parentBeginEnd = "Parent begin&end date: %s ~ %s"; +$lang->project->parentBudget = "The budget of the parent project: "; +$lang->project->beginLetterParent = "The begin date of the parent project: %s. It cannot be < the begin date of its parent project."; +$lang->project->endGreaterParent = "The end date of the parent project: %s. It cannot be > the end date of its parent project."; +$lang->project->beginGreateChild = 'La date de début du projets "%s" doit être ≥ à la date de début du programme "%s" : %s.'; +$lang->project->endLetterChild = 'La date de fin du projets doit être ≤ à la date de fin du programme: %s.'; +$lang->project->begigLetterExecution = 'La date de début du projet "%s" doit être ≤ à la date de début minimum d\'excution: %s'; +$lang->project->endGreateExecution = 'La date de fin du projet "%s" doit être ≥ à la date de fin maximale d\'exécution: %s.'; +$lang->project->childLongTime = "If a child as long-term projects, the parent should be long-term too."; +$lang->project->confirmUnlinkMember = "Do you want to remove this user from project?"; $lang->project->action = new stdclass(); $lang->project->action->managed = '$date, managed by $actor. $extra' . "\n"; diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php index 04edb713da..eacc6c49c0 100644 --- a/module/project/lang/zh-cn.php +++ b/module/project/lang/zh-cn.php @@ -310,18 +310,20 @@ $lang->project->programTitle['end'] = '只显示最后一级项目集'; $lang->project->accessDenied = '您无权访问该项目!'; $lang->project->chooseProgramType = '选择项目管理方式'; $lang->project->cannotCreateChild = '该项目已经有实际的内容,无法直接添加子项目。您可以为当前项目创建一个父项目,然后在新的父项目下面添加子项目。'; -$lang->project->hasChildren = '该项目有子项目存在,不能删除。'; -$lang->project->confirmDelete = '您确定删除项目“%s”吗?'; -$lang->project->cannotChangeToCat = "该项目已经有实际的内容,无法修改为父项目"; -$lang->project->cannotCancelCat = "该项目下已经有子项目,无法取消父项目标记"; -$lang->project->parentBeginEnd = "父项目起止时间:%s ~ %s"; -$lang->project->parentBudget = "父项目预算:"; -$lang->project->beginLetterParent = "父项目的开始日期:%s,开始日期不能小于父项目的开始日期"; -$lang->project->endGreaterParent = "父项目的完成日期:%s,完成日期不能大于父项目的完成日期"; -$lang->project->beginGreateChild = '项目“%s”的开始日期应大于等于项目集“%s”的最小开始日期:%s'; -$lang->project->endLetterChild = '项目“%s”的完成日期应小于等于项目集“%s”的最大完成日期:%s'; -$lang->project->childLongTime = "子项目中有长期项目,父项目也应该是长期项目"; -$lang->project->confirmUnlinkMember = "您确定从该项目中移除该用户吗?"; +$lang->project->hasChildren = '该项目有子项目存在,不能删除。'; +$lang->project->confirmDelete = '您确定删除项目“%s”吗?'; +$lang->project->cannotChangeToCat = "该项目已经有实际的内容,无法修改为父项目"; +$lang->project->cannotCancelCat = "该项目下已经有子项目,无法取消父项目标记"; +$lang->project->parentBeginEnd = "父项目起止时间:%s ~ %s"; +$lang->project->parentBudget = "父项目预算:"; +$lang->project->beginLetterParent = "父项目的开始日期:%s,开始日期不能小于父项目的开始日期"; +$lang->project->endGreaterParent = "父项目的完成日期:%s,完成日期不能大于父项目的完成日期"; +$lang->project->beginGreateChild = '项目的开始日期应大于等于项目集的最小开始日期:%s'; +$lang->project->endLetterChild = '项目的完成日期应小于等于项目集的最大完成日期:%s'; +$lang->project->begigLetterExecution = '项目的开始日期应小于等于执行的最小开始日期:%s'; +$lang->project->endGreateExecution = '项目的完成日期应大于等于执行的最大完成日期:%s'; +$lang->project->childLongTime = "子项目中有长期项目,父项目也应该是长期项目"; +$lang->project->confirmUnlinkMember = "您确定从该项目中移除该用户吗?"; $lang->project->action = new stdclass(); $lang->project->action->managed = '$date, 由 $actor 维护。$extra' . "\n"; diff --git a/module/project/model.php b/module/project/model.php index 7fc4a0f36e..88f4eee237 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -1094,10 +1094,10 @@ class projectModel extends model if($program) { /* Child project begin cannot less than parent. */ - if(!empty($project->name) and $project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $project->name, $program->name, $program->begin); + if(!empty($project->name) and $project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $program->begin); /* When parent set end then child project end cannot greater than parent. */ - if(!empty($project->name) and $$program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $project->name, $program->name, $program->end); + if(!empty($project->name) and $program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $program->end); if(dao::isError()) return false; } @@ -1358,10 +1358,10 @@ class projectModel extends model if($program) { /* Child project begin cannot less than parent. */ - if(!empty($project->name) and $project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $project->name, $program->name, $program->begin); + if(!empty($project->name) and $project->begin < $program->begin) dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $program->begin); /* When parent set end then child project end cannot greater than parent. */ - if(!empty($project->name) and $program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $project->name, $program->name, $program->end); + if(!empty($project->name) and $program->end != '0000-00-00' and $project->end > $program->end) dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $program->end); if(dao::isError()) return false; } @@ -1375,6 +1375,19 @@ class projectModel extends model } } + $executionsCount = $this->dao->select('COUNT(*) as count')->from(TABLE_PROJECT) + ->where('project')->eq($project->id) + ->andWhere('deleted')->eq('0') + ->fetchAll(); + if(!empty($executionsCount)) + { + $minExecutionBegin = $this->dao->select('begin as minBegin')->from(TABLE_PROJECT)->where('project')->eq($project->id)->andWhere('deleted')->eq('0')->orderBy('begin_asc')->fetch(); + $maxExecutionEnd = $this->dao->select('end as maxEnd')->from(TABLE_PROJECT)->where('project')->eq($project->id)->andWhere('deleted')->eq('0')->orderBy('end_desc')->fetch(); + if($minExecutionBegin and $project->begin > $minExecutionBegin->minBegin) dao::$errors['begin'] = sprintf($this->lang->project->begigLetterExecution, $minExecutionBegin->minBegin); + if($maxExecutionEnd and $project->end < $maxExecutionEnd->maxEnd) dao::$errors['end'] = sprintf($this->lang->project->endGreateExecution, $maxExecutionEnd->maxEnd); + if(dao::isError()) return false; + } + /* Judge products not empty. */ $linkedProductsCount = 0; foreach($_POST['products'] as $product) @@ -1529,14 +1542,14 @@ class projectModel extends model /* Child project begin cannot less than parent. */ if(!empty($projects[$projectID]->name) and $projects[$projectID]->begin < $parentProject->begin) { - dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $projects[$projectID]->name, $parentProject->name, $parentProject->begin); + dao::$errors['begin'] = sprintf($this->lang->project->beginGreateChild, $parentProject->begin); return false; } /* When parent set end then child project end cannot greater than parent. */ if(!empty($projects[$projectID]->name) and $parentProject->end != '0000-00-00' and $projects[$projectID]->end > $parentProject->end) { - dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $projects[$projectID]->name, $parentProject->name, $parentProject->end); + dao::$errors['end'] = sprintf($this->lang->project->endLetterChild, $parentProject->end); return false; } } diff --git a/module/search/view/buildform.html.php b/module/search/view/buildform.html.php index 0a1776aa68..482db3d259 100644 --- a/module/search/view/buildform.html.php +++ b/module/search/view/buildform.html.php @@ -284,15 +284,18 @@ function executeQuery(queryID) $(function() { - if(!canSaveQuery) $('.btn-save-form').attr('disabled', 'disabled'); - + if(!canSaveQuery) + { + $('.btn-save-form').attr('disabled', 'disabled'); + $('.btn-save-form').css('pointer-events', 'none'); + } var $searchForm = $('#'); $searchForm.find('select.chosen').chosen().on('chosen:showing_dropdown', function() { var $this = $(this); var $chosen = $this.next('.chosen-container').removeClass('chosen-up'); var $drop = $chosen.find('.chosen-drop'); - $chosen.toggleClass('chosen-up', $drop.height() + $drop.offset().top - $(document).scrollTop() > $(window).height()); + if($this.data('drop_direction') === 'auto') $chosen.toggleClass('chosen-up', $drop.height() + $drop.offset().top - $(document).scrollTop() > $(window).height()); }); $searchForm.find('.picker-select').each(function() diff --git a/module/setting/model.php b/module/setting/model.php index cfbf2020e3..b313485796 100644 --- a/module/setting/model.php +++ b/module/setting/model.php @@ -194,6 +194,8 @@ class settingModel extends model ->fetchAll('id'); if(!$records) return array(); + $vision = $this->config->vision; + /* Group records by owner and module. */ $config = array(); foreach($records as $record) @@ -202,6 +204,9 @@ class settingModel extends model if(!isset($record->module)) return array(); // If no module field, return directly. Since 3.2 version, there's the module field. if(empty($record->module)) continue; + /* If it`s lite vision unset config requiredFields */ + if($vision == 'lite' and $record->key == 'requiredFields' and $record->vision == '') continue; + $config[$record->owner]->{$record->module}[] = $record; } return $config; diff --git a/module/story/control.php b/module/story/control.php index a97bad0cb6..87cfc0166f 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -1284,10 +1284,11 @@ class story extends control $this->view->position[] = $this->lang->story->common; $this->view->position[] = $this->lang->story->review; - $this->view->product = $product; - $this->view->story = $story; - $this->view->actions = $this->action->getList('story', $storyID); - $this->view->users = $this->loadModel('user')->getPairs('nodeleted', "$story->lastEditedBy,$story->openedBy"); + $this->view->product = $product; + $this->view->story = $story; + $this->view->actions = $this->action->getList('story', $storyID); + $this->view->users = $this->loadModel('user')->getPairs('nodeleted|noletter', "$story->lastEditedBy,$story->openedBy"); + $this->view->reviewers = $reviewers; /* Get the affcected things. */ $this->story->getAffectedScope($this->view->story); @@ -2591,4 +2592,69 @@ class story extends control } echo $status; } + + /** + * Ajax get story assignee. + * + * @param string $type create|review|change + * @param int $storyID + * @param array $assignees + * + * @access public + * @return void + */ + public function ajaxGetAssignedTo($type = '', $storyID = 0, $assignees = '') + { + $users = $this->loadModel('user')->getPairs('noletter|noclosed'); + + if($type == 'create') + { + $selectUser = is_array($assignees) ? current($assignees) : ''; + + return print(html::select('assignedTo', $users, $selectUser, "class='from-control picker-select'")); + } + + if($type == 'review') + { + $story = $this->story->getByID($storyID); + $reviewers = $this->story->getReviewerPairs($storyID, $story->version); + $isChanged = $story->changedBy ? true : false; + $isSuperReviewer = strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . $this->app->user->account . ','); + + if(count($reviewers) == 1) + { + $selectUser = $isChanged ? $story->changedBy : $story->openedBy; + } + else + { + unset($reviewers[$this->app->user->account]); + foreach($reviewers as $account => $result) + { + if(!$reviewers[$account]) + { + $selectUser = $account; + break; + } + else + { + $selectUser = $isChanged ? $story->changedBy : $story->openedBy; + } + } + } + + if($isSuperReviewer !== false) $selectUser = $isChanged ? $story->changedBy : $story->openedBy; + + return print(html::select('assignedTo', $users, $selectUser, "class='from-control picker-select'")); + } + + if($type == 'change') + { + $selectUser = is_array($assignees) ? current($assignees) : ''; + + return print(html::select('assignedTo', $users, $selectUser, "class='from-control picker-select'")); + } + + return false; + + } } diff --git a/module/story/js/change.js b/module/story/js/change.js index bdab28bdaa..4a33c6cb57 100644 --- a/module/story/js/change.js +++ b/module/story/js/change.js @@ -11,8 +11,39 @@ $(function() { $('.input-group-addon').addClass('required'); } + + loadAssignedTo(); }); $('#needNotReview').change(); if($('.tabs .tab-content .tab-pane.active').children().length == 0) $('.tabs .nav-tabs li.active').css('border-bottom', '1px solid #ccc'); }); + +/** + * Load assignedTo. + * + * @access public + * @return void + */ +function loadAssignedTo() +{ + var assignees = $('#reviewer').val(); + var link = createLink('story', 'ajaxGetAssignedTo', 'type=change&storyID=' + storyID + '&assignees=' + assignees); + $.post(link, function(data) + { + $('#assignedTo').replaceWith(data); + $('#assignedToBox .picker').remove(); + $('#assignedTo').picker(); + }); + + if($('#needNotReview').is(':checked')) + { + $('#assignedToBox').removeClass('hidden'); + $('#reviewerBox').attr('colspan', 1); + } + else + { + $('#assignedToBox').addClass('hidden'); + $('#reviewerBox').attr('colspan', 2); + } +} diff --git a/module/story/js/create.js b/module/story/js/create.js index 938aa71652..0dc61da541 100644 --- a/module/story/js/create.js +++ b/module/story/js/create.js @@ -11,6 +11,7 @@ $(function() { $('#reviewerBox').addClass('required'); } + loadAssignedTo(); getStatus('create', "product=" + $('#product').val() + ",execution=" + executionID + ",needNotReview=" + ($(this).prop('checked') ? 1 : 0)); }); @@ -33,16 +34,48 @@ $(function() if($.inArray(source, feedbackSource) != -1) { $('#feedbackBox').removeClass('hidden'); - $('#reviewerBox').attr('colspan', 2); + $('#reviewerBox').attr('colspan', 1); + $('#assignedToBox').attr('colspan', 1); } else { $('#feedbackBox').addClass('hidden'); - $('#reviewerBox').attr('colspan', 4); + $('#reviewerBox').attr('colspan', 2); + $('#assignedToBox').attr('colspan', 2); } }); }); +/** + * Load assignedTo. + * + * @access public + * @return void + */ +function loadAssignedTo() +{ + var assignees = $('#reviewer').val(); + var link = createLink('story', 'ajaxGetAssignedTo', 'type=create&storyID=0&assignees=' + assignees); + $.post(link, function(data) + { + $('#assignedTo').replaceWith(data); + $('#assignedToBox .picker').remove(); + $('#assignedTo').picker(); + }); + + var colspan = $('#assignedToBox').attr('colspan'); + if($('#needNotReview').is(':checked')) + { + $('#assignedToBox').removeClass('hidden'); + $('#reviewerBox').attr('colspan', colspan); + } + else + { + $('#assignedToBox').addClass('hidden'); + $('#reviewerBox').attr('colspan', colspan * 2); + } +} + function refreshPlan() { loadProductPlans($('#product').val(), $('#branch').val()); diff --git a/module/story/js/review.js b/module/story/js/review.js index 0ffa50543d..b310cfa1d6 100644 --- a/module/story/js/review.js +++ b/module/story/js/review.js @@ -6,6 +6,8 @@ function switchShow(result) { $('#rejectedReasonBox').show(); $('#preVersionBox').hide(); + $('#assignedToBox').hide(); + if(isMultiple) loadAssignedTo(); } else if(result == 'revert') { @@ -13,19 +15,34 @@ function switchShow(result) $('#rejectedReasonBox').hide(); $('#duplicateStoryBox').hide(); $('#childStoriesBox').hide(); + $('#assignedToBox').show(); + loadAssignedTo(); } - else + else if(result == 'clarify') { - if(result == 'pass') - { - $('#priBox').show(); - $('#estimateBox').show(); - } $('#preVersionBox').hide(); $('#rejectedReasonBox').hide(); $('#duplicateStoryBox').hide(); $('#childStoriesBox').hide(); $('#rejectedReasonBox').hide(); + $('#assignedToBox').show(); + loadAssignedTo(); + } + else + { + $('#preVersionBox').hide(); + $('#rejectedReasonBox').hide(); + $('#duplicateStoryBox').hide(); + $('#childStoriesBox').hide(); + $('#rejectedReasonBox').hide(); + $('#assignedToBox').hide(); + if(result == 'pass') + { + $('#priBox').show(); + $('#estimateBox').show(); + $('#assignedToBox').show(); + loadAssignedTo(); + } } getStatus('review', "storyID=" + storyID + ",result=" + result); @@ -50,6 +67,23 @@ function setStory(reason) } } +/** + * Load assignedTo. + * + * @access public + * @return void + */ +function loadAssignedTo() +{ + var link = createLink('story', 'ajaxGetAssignedTo', 'type=review&storyID=' + storyID); + $.post(link, function(data) + { + $('#assignedTo').replaceWith(data); + $('#assignedToBox .picker').remove(); + $('#assignedTo').picker(); + }); +} + $(function() { if($('.tabs .tab-content .tab-pane.active').children().length == 0) $('.tabs .nav-tabs li.active').css('border-bottom', '1px solid #ccc'); diff --git a/module/story/model.php b/module/story/model.php index a62f81c3e1..605f04d858 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -219,6 +219,7 @@ class storyModel extends model ->setIF(!in_array($this->post->source, $this->config->story->feedbackSource), 'notifyEmail', '') ->setIF($executionID > 0, 'stage', 'projected') ->setIF($bugID > 0, 'fromBug', $bugID) + ->join('assignedTo', '') ->join('mailto', ',') ->stripTags($this->config->story->editor->create['id'], $this->config->allowedTags) ->remove('files,labels,reviewer,needNotReview,newStory,uid,contactListMenu,URS,region,lane') @@ -676,10 +677,13 @@ class storyModel extends model ->setDefault('lastEditedBy', $this->app->user->account) ->add('id', $storyID) ->add('lastEditedDate', $now) + ->setIF(!$this->post->assignedTo, 'assignedTo', '') ->setIF($specChanged, 'version', $oldStory->version + 1) ->setIF($specChanged and $oldStory->status == 'active' and $this->post->needNotReview == false, 'status', 'changed') ->setIF($oldStory->status == 'draft' and $this->post->needNotReview, 'status', 'active') ->setIF($specChanged, 'reviewedBy', '') + ->setIF($specChanged, 'changedBy', $this->app->user->account) + ->setIF($specChanged, 'changedDate', $now) ->setIF($specChanged, 'closedBy', '') ->setIF($specChanged, 'closedReason', '') ->setIF($specChanged and $oldStory->reviewedBy, 'reviewedDate', '0000-00-00') @@ -1329,6 +1333,7 @@ class storyModel extends model ->setDefault('status', $oldStory->status) ->setDefault('reviewedDate', $date) ->stripTags($this->config->story->editor->review['id'], $this->config->allowedTags) + ->setIF(!$this->post->assignedTo, 'assignedTo', '') ->setIF($this->post->result == 'revert', 'version', $this->post->preVersion) ->setIF($this->post->result == 'clarify', 'assignedTo', $oldStory->lastEditedBy ? $oldStory->lastEditedBy : $oldStory->openedBy) ->removeIF($this->post->result != 'reject', 'closedReason, duplicateStory, childStories') @@ -3887,7 +3892,8 @@ class storyModel extends model $menu .= $this->buildMenu('story', 'close', $params, $story, $type, '', '', 'iframe', true); $menu .= $this->buildMenu('story', 'edit', $params . "&from=$story->from", $story, $type); - if($story->type != 'requirement' and $this->config->vision != 'lite') $menu .= $this->buildMenu('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=¶m=0&$params", $story, $type, 'sitemap', '', '', false, "data-app='qa'"); + $tab = $this->app->tab == 'project' ? 'project' : 'qa'; + if($story->type != 'requirement' and $this->config->vision != 'lite') $menu .= $this->buildMenu('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=¶m=0&$params", $story, $type, 'sitemap', '', '', false, "data-app='$tab'"); if($this->app->rawModule != 'projectstory' OR $this->config->vision == 'lite') { @@ -4015,7 +4021,7 @@ class storyModel extends model if($canBeChanged and common::hasPriv('execution', 'storyEstimate', $execution)) { - $menu .= common::printIcon('execution', 'storyEstimate', "executionID=$executionID&storyID=$story->id", '', 'list', 'estimate', '', 'iframe', true, "data-width='450px'"); + $menu .= common::printIcon('execution', 'storyEstimate', "executionID=$executionID&storyID=$story->id", '', 'list', 'estimate', '', 'iframe', true, "data-width='470px'"); } if($canBeChanged and common::hasPriv('execution', 'unlinkStory', $execution)) diff --git a/module/story/view/change.html.php b/module/story/view/change.html.php index 79333c1e1e..893a942896 100644 --- a/module/story/view/change.html.php +++ b/module/story/view/change.html.php @@ -24,7 +24,7 @@ - + diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php index 65afdf1cae..d86cb8df14 100644 --- a/module/story/view/create.html.php +++ b/module/story/view/create.html.php @@ -103,7 +103,7 @@ - + - + + + + + @@ -85,4 +89,5 @@ id);?> type);?> app->rawModule);?> + diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php index c2a92ef17e..14ff9d6f1c 100644 --- a/module/story/view/view.html.php +++ b/module/story/view/view.html.php @@ -307,7 +307,7 @@ - + diff --git a/module/task/control.php b/module/task/control.php index f55ed55380..e46a6399c5 100755 --- a/module/task/control.php +++ b/module/task/control.php @@ -44,7 +44,8 @@ class task extends control $extra = str_replace(array(',', ' '), array('&', ''), $extra); parse_str($extra, $output); - $executions = $this->execution->getPairs(0, 'all', 'noclosed'); + $execution = $this->execution->getById($executionID); + $executions = $this->execution->getPairs(0, 'all', !common::canModify('execution', $execution) ? 'noclosed' : ''); $executionID = $this->execution->saveState($executionID, $executions); $this->execution->setMenu($executionID); @@ -92,7 +93,6 @@ class task extends control $task->assignedTo = array($bug->assignedTo); } - $execution = $this->execution->getById($executionID); $taskLink = $this->createLink('execution', 'browse', "executionID=$executionID&tab=task"); $this->loadModel('kanban'); @@ -283,7 +283,7 @@ class task extends control $this->view->position = $position; $this->view->gobackLink = (isset($output['from']) and $output['from'] == 'global') ? $this->createLink('execution', 'task', "executionID=$executionID") : ''; $this->view->execution = $execution; - $this->view->executions = $this->config->systemMode == 'classic' ? $executions : $this->execution->getByProject($projectID, 'undone', 0, true); + $this->view->executions = $this->config->systemMode == 'classic' ? $executions : $this->execution->getByProject($projectID, !common::canModify('execution', $execution) ? 'noclosed' : 'all', 0, true); $this->view->task = $task; $this->view->users = $users; $this->view->storyID = $storyID; @@ -831,6 +831,7 @@ class task extends control { if(isset($muletipleTasks[$taskID]) and $task->assignedTo != $this->app->user->account and $task->mode == 'linear') continue; if(isset($muletipleTasks[$taskID]) and !isset($muletipleTasks[$taskID][$this->post->assignedTo])) continue; + if($task->status == 'closed') continue; $changes = $this->task->assign($taskID); if(dao::isError()) return print(js::error(dao::getError())); diff --git a/module/task/js/batchcreate.js b/module/task/js/batchcreate.js index b98330264c..cccca95207 100755 --- a/module/task/js/batchcreate.js +++ b/module/task/js/batchcreate.js @@ -136,12 +136,14 @@ function setPreview(num) storyLink = storyLink + concat + 'onlybody=yes'; } $('#preview' + num).removeAttr('disabled'); + $('#preview' + num).modalTrigger({type:'iframe'}); $('#preview' + num).attr('href', storyLink); } else { storyLink = '#'; $('#preview' + num).attr('disabled', true); + $('#preview' + num).css('pointer-events', 'none'); $('#preview' + num).attr('href', storyLink); } } diff --git a/module/task/model.php b/module/task/model.php index f60cd711f2..80ec3d883b 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -831,7 +831,7 @@ class taskModel extends model $currentTask->consumed += (float)$member->consumed; $currentTask->left += (float)$member->left; } - if(empty($oldTask->team)) $currentTask->consumed += (float)$oldTask->consumed; + if(empty($oldTask->team) and isset($oldTask->consumed)) $currentTask->consumed += (float)$oldTask->consumed; if(!empty($task)) { @@ -3582,7 +3582,7 @@ class taskModel extends model $btnClass = $task->assignedTo == 'closed' ? ' disabled' : ''; $btnClass = "iframe btn btn-icon-left btn-sm {$btnClass}"; - $assignToLink = helper::createLink('task', 'assignTo', "executionID=$task->execution&taskID=$task->id", '', true); + $assignToLink = $task->assignedTo == 'closed' ? '#' : helper::createLink('task', 'assignTo', "executionID=$task->execution&taskID=$task->id", '', true); $assignToHtml = html::a($assignToLink, "{$assignedToText}", '', "class='$btnClass'"); echo !common::hasPriv('task', 'assignTo', $task) ? "{$assignedToText}" : $assignToHtml; @@ -3729,7 +3729,8 @@ class taskModel extends model $menu .= $this->buildMenu('task', 'batchCreate', "execution=$task->execution&storyID=$task->story&moduleID=$task->module&taskID=$task->id", $task, 'view', 'split', '', '', '', "title='{$this->lang->task->children}'", $this->lang->task->children); } - if(!(!empty($task->team) and $task->mode == 'multi')) $menu .= $this->buildMenu('task', 'assignTo', "executionID=$task->execution&taskID=$task->id", $task, 'button', '', '', 'iframe', true, '', empty($task->team) ? $this->lang->task->assignTo : $this->lang->task->transfer); + $assignToLang = (!empty($task->team) and $task->mode == 'linear') ? $this->lang->task->transfer : $this->lang->task->assignTo; + $menu .= $this->buildMenu('task', 'assignTo', "executionID=$task->execution&taskID=$task->id", $task, 'button', '', '', 'iframe', true, '', $assignToLang); $menu .= $this->buildMenu('task', 'start', $params, $task, 'view', '', '', 'iframe showinonlybody', true); $menu .= $this->buildMenu('task', 'restart', $params, $task, 'view', '', '', 'iframe showinonlybody', true); diff --git a/module/task/view/batchcreate.html.php b/module/task/view/batchcreate.html.php index 02d295aad4..7c3f837fe0 100755 --- a/module/task/view/batchcreate.html.php +++ b/module/task/view/batchcreate.html.php @@ -197,7 +197,7 @@
    - +
    diff --git a/module/task/view/finish.html.php b/module/task/view/finish.html.php index 0e4085b0f5..6c855dff64 100644 --- a/module/task/view/finish.html.php +++ b/module/task/view/finish.html.php @@ -66,7 +66,7 @@ - + diff --git a/module/task/view/view.html.php b/module/task/view/view.html.php index c4a4d4f31b..e2f4091aa7 100644 --- a/module/task/view/view.html.php +++ b/module/task/view/view.html.php @@ -166,7 +166,7 @@
    - + ' . $lang->goback, '', "class='btn btn-secondary'");?>
    ";?> executionList = $execution;?> task->buildOperateMenu($task, 'view');?> diff --git a/module/testcase/control.php b/module/testcase/control.php index 2d4fb9a109..fda3c10423 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -1582,6 +1582,10 @@ class testcase extends control $case->real = ''; $result = isset($results[$case->id]) ? $results[$case->id] : array(); + $case->openedDate = !helper::isZeroDate($case->openedDate) ? $case->openedDate : ''; + $case->lastEditedDate = !helper::isZeroDate($case->lastEditedDate) ? $case->lastEditedDate : ''; + $case->lastRunDate = !helper::isZeroDate($case->lastRunDate) ? $case->lastRunDate : ''; + $case->real = ''; if(!empty($result) and !isset($relatedSteps[$case->id])) { @@ -2168,11 +2172,11 @@ class testcase extends control */ public function importToLib($caseID = 0) { - $caseIDList = $this->post->caseIDList; - if(!empty($_POST)) + if($this->server->request_method == 'POST') { $this->testcase->importToLib($caseID); - if(!empty($caseID)) return $this->send(array('result' => 'success', 'message' => $this->lang->importSuccess, 'closeModal' => true,)); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + if(!empty($caseID)) return $this->send(array('result' => 'success', 'message' => $this->lang->importSuccess, 'closeModal' => true)); return $this->send(array('result' => 'success', 'message' => $this->lang->importSuccess, 'locate' => 'reload')); } $this->view->libraries = $this->loadModel('caselib')->getLibraries(); diff --git a/module/testcase/js/common.js b/module/testcase/js/common.js index d68f4b183f..e15400f349 100644 --- a/module/testcase/js/common.js +++ b/module/testcase/js/common.js @@ -403,7 +403,7 @@ function loadStories(productID, moduleID, num) */ function setModules(branchID, productID, num) { - moduleLink = createLink('tree', 'ajaxGetModules', 'productID=' + productID + '&viewType=story&branch=' + branchID + '&num=' + num); + moduleLink = createLink('tree', 'ajaxGetModules', 'productID=' + productID + '&viewType=case&branch=' + branchID + '&num=' + num); $.get(moduleLink, function(modules) { if(!modules) modules = ''; diff --git a/module/testcase/lang/de.php b/module/testcase/lang/de.php index 49cc37dfb2..75a624b4fc 100644 --- a/module/testcase/lang/de.php +++ b/module/testcase/lang/de.php @@ -94,6 +94,7 @@ $lang->testcase->mailto = 'Mailto'; $lang->testcase->deleted = 'Deleted'; $lang->testcase->browseUnits = 'Unit Test'; $lang->testcase->suite = 'Test Suite'; +$lang->testcase->lib = 'Lib'; $lang->case = $lang->testcase; // For dao checking using. Because 'case' is a php keywords, so the module name is testcase, table name is still case. diff --git a/module/testcase/lang/en.php b/module/testcase/lang/en.php index bf6b80c707..9bb76c9391 100644 --- a/module/testcase/lang/en.php +++ b/module/testcase/lang/en.php @@ -94,6 +94,7 @@ $lang->testcase->mailto = 'Mailto'; $lang->testcase->deleted = 'Deleted'; $lang->testcase->browseUnits = 'Unit Test'; $lang->testcase->suite = 'Test Suite'; +$lang->testcase->lib = 'Lib'; $lang->case = $lang->testcase; // For dao checking using. Because 'case' is a php keywords, so the module name is testcase, table name is still case. diff --git a/module/testcase/lang/fr.php b/module/testcase/lang/fr.php index 3a17ba1246..7e57f446e8 100644 --- a/module/testcase/lang/fr.php +++ b/module/testcase/lang/fr.php @@ -94,6 +94,7 @@ $lang->testcase->mailto = 'Mailto'; $lang->testcase->deleted = 'Deleted'; $lang->testcase->browseUnits = 'Unit Test'; $lang->testcase->suite = 'Test Suite'; +$lang->testcase->lib = 'Lib'; $lang->case = $lang->testcase; // For dao checking using. Because 'case' is a php keywords, so the module name is testcase, table name is still case. diff --git a/module/testcase/lang/zh-cn.php b/module/testcase/lang/zh-cn.php index 74b485c9e9..c439aa93be 100644 --- a/module/testcase/lang/zh-cn.php +++ b/module/testcase/lang/zh-cn.php @@ -94,6 +94,7 @@ $lang->testcase->mailto = '抄送给'; $lang->testcase->deleted = '是否删除'; $lang->testcase->browseUnits = '单元测试'; $lang->testcase->suite = '套件'; +$lang->testcase->lib = '用例库'; $lang->case = $lang->testcase; // 用于DAO检查时使用。因为case是系统关键字,所以无法定义该模块为case,只能使用testcase,但表还是使用的case。 diff --git a/module/testcase/model.php b/module/testcase/model.php index 9e8e8a45b4..90c8d2e501 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -1670,8 +1670,9 @@ class testcaseModel extends model $caseIdList = explode(',' , $caseIdList); $libID = $this->post->lib; - $this->loadModel('action'); + if(empty($libID)) return dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->testcase->lib); + $this->loadModel('action'); $cases = $this->dao->select('*')->from(TABLE_CASE)->where('deleted')->eq(0)->andWhere('id')->in($caseIdList)->fetchAll('id'); $caseSteps = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->in($caseIdList)->orderBy('id')->fetchGroup('case'); $caseFiles = $this->dao->select('*')->from(TABLE_FILE)->where('objectID')->in($caseIdList)->andWhere('objectType')->eq('testcase')->fetchGroup('objectID', 'id'); diff --git a/module/testtask/js/common.js b/module/testtask/js/common.js index 98acc21e3f..26df905e98 100644 --- a/module/testtask/js/common.js +++ b/module/testtask/js/common.js @@ -36,7 +36,8 @@ function adjustPriBoxWidth() var boxWidth = $('#ownerAndPriBox').width(); var beginWidth = $("input[name='begin']").outerWidth(); var addonWidth = $('#ownerAndPriBox .input-group-addon').outerWidth(); - $('#pri,#pri_chosen .chosen-single').css('width', boxWidth - beginWidth -addonWidth); + var width = boxWidth - beginWidth - addonWidth; + $('#pri,#pri_chosen .chosen-single').css('width', width > 0 ? width : '160px'); } /** diff --git a/module/testtask/js/edit.js b/module/testtask/js/edit.js index c60cf07c54..2e8300669a 100755 --- a/module/testtask/js/edit.js +++ b/module/testtask/js/edit.js @@ -1,4 +1,5 @@ $(function() { adjustPriBoxWidth(); + if(config.onlybody) $('#ownerAndPriBox .picker-selection').css('width', '123px'); }) diff --git a/module/testtask/view/linkcase.html.php b/module/testtask/view/linkcase.html.php index 07ad73eac5..821c398f65 100644 --- a/module/testtask/view/linkcase.html.php +++ b/module/testtask/view/linkcase.html.php @@ -14,7 +14,7 @@
    story->reviewedBy;?> +
    story->checkForceReview() ? ' required' : ''));?> story->checkForceReview()):?> @@ -34,6 +34,12 @@
    +
    +
    story->assignedTo;?>
    + +
    +
    story->status;?>
    story->reviewedBy;?>' id='reviewerBox'> + ' id='reviewerBox'>
    story->checkForceReview()):?>
    @@ -124,6 +124,12 @@
    ' id='assignedToBox'> +
    +
    story->assignedTo;?>
    + +
    +
    diff --git a/module/story/view/review.html.php b/module/story/view/review.html.php index 1e1d20a6dc..73cfdc29d5 100644 --- a/module/story/view/review.html.php +++ b/module/story/view/review.html.php @@ -29,7 +29,11 @@
    story->reviewResult;?>story->resultList, '', 'class=form-control onchange="switchShow(this.value)"');?>story->resultList, '', 'class="form-control chosen" onchange="switchShow(this.value)"');?>
    story->assignedTo;?>
    story->rejectedReason;?>
    story->category;?>story->categoryList[$story->category];?>story->categoryList, $story->category, $story->category)?>
    story->pri;?>
    team) ? $lang->task->assign : $lang->task->transferTo;?>team) and $task->mode == 'linear') ? $lang->task->transferTo : $lang->task->assign;?> nextBy, "class='form-control chosen'");?>
    ').addClass(i.attr("class")).append(n.clone())).insertAfter(i)),h){var d=c[0].getBoundingClientRect();l.css({left:d.left,width:c.width(),overflow:"hidden"}),l.find(".fixed-header-copy").css({left:o.left-d.left,position:"relative",minWidth:i.width()}),a||c.data("fixHeaderScroll")||(c.data("fixHeaderScroll",1),i.width()>c.width()&&c.on("scroll",function(){e.fixHeader()}))}else l.css({left:o.left,width:o.width});var u=l.find("th");n.find("th").each(function(e){u.eq(e).css("width",t(this).outerWidth())})}else l.remove()},r.prototype.fixFooter=function(){var e,i=this,n=i.getTable(),o=i.$.find(".table-footer");if(i.isDataTable)e=n[0].getBoundingClientRect();else{var a=n.find("tbody");if(!a.length)return;e=a[0].getBoundingClientRect()}var s=i.options.fixFooter;o.toggleClass("fixed-footer",!!r);var r="function"==typeof s?s(e,o):e.bottom>window.innerHeight-50-("number"==typeof s?s:i.pageFooterHeight||5);o.toggleClass("fixed-footer",!!r),n.toggleClass("with-footer-fixed",!!r),n.trigger("fixFooter",r);var l=t("body"),c=l.hasClass("body-modal");if(r){var h=n.parent(),d=h.is(".table-responsive");o.css({bottom:i.pageFooterHeight||0,left:d?h[0].getBoundingClientRect().left:e.left,width:d?h.width():e.width}),c&&l.css("padding-bottom",40)}else o.css({width:"",left:0,bottom:0}),c&&l.css("padding-bottom",0)},r.prototype.checkAll=function(e){var i=this,n=i.$.find(i.isDataTable?".fixed-left tbody>tr":"tbody>tr");n.each(function(){i.checkRow(t(this),e,!0)}),i.updateCheckUI()},r.prototype.checkRow=function(i,n,o){var a=this,s=a.getTable();a.isDataTable&&!i.is(".datatable-row-left")&&(i=s.find('.datatable-row-left[data-index="'+i.data("index")+'"]'));var r=i.find('input[type="checkbox"]');if(r.length&&!r.is(":disabled")){n===e&&(n=!r.is(":checked")),a.isDataTable?s.find('.datatable-row[data-index="'+i.data("index")+'"]').toggleClass("checked",n):i.toggleClass("checked",n);var l=i.data("id");this.checkItems[l]=n,r.prop("checked",n).trigger("change"),o||(i.hasClass("table-parent")&&s.find((a.isDataTable?".fixed-left ":"")+"tbody>tr.parent-"+l).each(function(){a.checkRow(t(this),n,!0)}),a.updateCheckUI())}},r.prototype.updateCheckUI=function(){var e=this,i=e.getTable(),n=i.find(e.isDataTable?".fixed-left tbody>tr":"tbody>tr").not(".group-summary"),o=!1,a=null,s=0,r=!1,l=n.length;n.each(function(n){var c=t(this),h=c.find('input[type="checkbox"]');if(!h.length)return void l--;r=h.is(":checked");var d=e.isDataTable?i.find('.datatable-row[data-index="'+c.data("index")+'"]'):c;d.toggleClass("checked",r),d.toggleClass("row-check-begin",r&&!o),a&&a.toggleClass("row-check-end",!r&&o),r&&(s+=1),a=d,o=r,l===n+1&&d.toggleClass("row-check-end",r)}),e.$.toggleClass("has-row-checked",s>0).find(".check-all").toggleClass("checked",!(!l||s!==l)),e.updateStatistic(),e.options.onCheckChange&&e.options.onCheckChange(),i.trigger("checkChange")},r.DEFAULTS={checkable:!0,checkOnClickRow:!0,ajaxForm:!1,selectable:!0,fixHeader:!a,fixFooter:!a,iframeWidth:900,replaceId:"self",nestLevelIndent:18,nested:!1,preserveNested:!0,hot:!1,iframeModalTrigger:".iframe:not(.disabled,[disabled])"},t.fn.table=function(e){return this.each(function(){var n=t(this),o=n.data(i),a="object"==typeof e&&e;o||n.data(i,o=new r(this,a)),"string"==typeof e&&o[e]()})},r.NAME=i,t.fn.table.Constructor=r,t(function(){t('[data-ride="table"]').table()}); -}(jQuery,void 0),function(t,e,i){t.fn._ajaxForm=t.fn.ajaxForm;var n={timeout:e.config?e.config.timeout:0,dataType:"json",method:"post"},o="";t.fn.enableForm=function(e,n,o){return e===i&&(e=!0),this.each(function(){var i=t(this);n||i.find('[type="submit"]').attr("disabled",e?null:"disabled"),!o&&i.hasClass("load-indicator")&&i.toggleClass("loading",!e),i.toggleClass("form-disabled",!e)})},t.enableForm=function(e,i,n,o){"string"==typeof e||e instanceof t?e=t(e):(o=n,n=i,i=e,e=t("form")),e.enableForm(i!==!1,n,o)},t.disableForm=function(e,i,n){t.enableForm(e,!1,i,n)};var a=function(e,i,n){"string"==typeof i&&(n=i,i=null),n=n||"show",t.zui.messager?t.zui.messager[n](e,i):alert(e)};t.ajaxForm=function(s,r){var l=t(s);if(l.length>1)return l.each(function(){t.ajaxForm(this,r)});"function"==typeof r&&(r={complete:r}),r=t.extend({},n,l.data(),r);var c=r.beforeSubmit,h=r.error,d=r.success,u=r.finish;delete r.finish,delete r.success,delete r.onError,delete r.beforeSubmit,r=t.extend({beforeSubmit:function(n,a,s){if((c&&c(n,a,s))===!1)return!1;l.removeClass("form-watched").enableForm(!1);var r={},h=a.find('[type="file"]');r.fileapi=h.length&&h[0].files!==i,r.formdata=e.FormData!==i;var d=r.fileapi&&a.find('input[type="file"]:enabled').filter(function(){return""!==t(this).val()}),u=d.length,p="multipart/form-data",f=a.attr("enctype")==p||a.attr("encoding")==p,g=r.fileapi&&r.formdata,m=u&&!g||f&&!r.formdata;m&&(""==o&&(o=s.url),s.url!=o&&(s.url=o),s.url=s.url.indexOf("&")>=0?s.url+"&HTTP_X_REQUESTED_WITH=XMLHttpRequest":s.url+"?HTTP_X_REQUESTED_WITH=XMLHttpRequest")},success:function(i,n,o){if((d&&d(i,n,o,l))!==!1){try{"string"==typeof i&&(i=JSON.parse(i))}catch(s){}if(null===i||"object"!=typeof i)return i?alert(i):a("No response.","danger");var c=r.responser?t(r.responser):l.find(".form-responser");c.length||(c=t("#responser"));var h=i.message,p=function(){var n=i.callback;if(n)if("object"==typeof n){var o=n.target?e[n.target]:e,a=o[n.name];a.apply(l,Array.isArray(n.params)?n.params:[n.params])}else{var s=n.indexOf("("),r=(s>0?n.substr(0,s):n).split("."),c=e,h=r[0];r.length>1&&(h=r[1],"top"===r[0]?c=e.top:"parent"===r[0]&&(c=e.parent));var a=c[h];if("function"==typeof a){var d=[];return s>0&&")"==n[n.length-1]&&(d=t.parseJSON("["+n.substring(s+1,n.length-1)+"]")),d.push(i),a.apply(l,d)}}};if("success"===i.result){var f=r.locate||i.locate,g=r.closeModal||i.closeModal,m=r.ajaxReload||i.ajaxReload;if(l.enableForm(!0,!!(f||g||m)),h){var v=l.find('[type="submit"]').first(),y=!1;v.length&&(v.popover({container:"body",trigger:"manual",content:h,tipClass:"popover-in-modal popover-success popover-form-result",placement:i.placement||v.data("placement")||r.popoverPlacement||"right"}).popover("show"),setTimeout(function(){v.popover("destroy")},r.popoverTime||2e3),y=!0),c.length&&(c.html(''+h+"").show().delay(3e3).fadeOut(100),y=!0),y||a(h,"success")}if(u)return u(i,!0,l);if(g&&setTimeout(t.zui.closeModal,"number"==typeof g?g:r.closeModalTime||2e3),p()===!1)return;if(f)if("loadInModal"==f){var b=t(".modal");setTimeout(function(){b.load(b.attr("ref"),function(){t(this).find(".modal-dialog").css("width",t(this).data("width")),t.zui.ajustModalPosition()})},1e3)}else"parent"===f||"top"===f?e[f]&&setTimeout(function(){e[f].location.reload()},1200):"reload"===f?setTimeout(function(){e.location.href=e.location.href},1200):setTimeout(function(){t.apps?t.apps.open(f):e.location.href=f},1200);if(m){var w=t(m);w.length&&w.load(e.location.href+" "+m,function(){w.find('[data-toggle="modal"]').modalTrigger()})}}else{if(l.enableForm(),"string"==typeof h)c.length?c.html(''+h+"").show().delay(3e3).fadeOut(100):a(h,"danger");else if("object"==typeof h){var x=!1,C=[];t.each(h,function(e,i){var n=t.isArray(i)?i.join(""):i,o=t("#"+e);if(!o.length)return void C.push(n);var a=e+"Label",s=t("#"+a);if(!s.length){var r=o.closest(".input-group").length,l=o.closest("td").length;s=t('
    ').appendTo(l?o.closest("td"):r?o.closest(".input-group").parent():o.parent())}s.empty().append(n),o.addClass("has-error");var c=function(){var e=t("#"+a);if(e.length)return e.remove(),o.removeClass("has-error"),!0};o.on("change input mousedown",c);var h=t("#"+e+"_chosen");if(h.length&&h.find(".chosen-single,.chosen-choices").addClass("has-error").on("mousedown",function(){c()===!0&&t(this).removeClass("has-error")}),!x){var d=o[0];if(o.hasClass("chosen"))o.trigger("chosen:activate").trigger("chosen:open"),d=o.parent().find(".chosen-container")[0];else if(o.is("textarea")&&o.data("keditor")){var u=o.data("keditor");u.focus(),u.edit.doc.body.focus(),d=o.parent().find(".ke-container")[0]}else o.focus();d.scrollIntoView&&d.scrollIntoView(),x=!0}}),C.length&&a(C.join(";"),"danger")}if(u)return u(i,!1,l);if(p()===!1)return}}},error:function(t,i,n){if((h&&h(t,i,n,l))!==!1){l.enableForm();var o="timeout"==i||"error"==i?e.lang?e.lang.timeout:i:t.responseText+i+n;a(o,"danger")}}},r),l._ajaxForm(r).data("zui.ajaxform",!0),l.on("click","[data-form-action]",function(){l.attr("action",t(this).data("formAction")).submit()})},t.setAjaxForm=function(e,i,n){t.ajaxForm(e,t.isPlainObject(i)?i:{finish:i,beforeSubmit:n})},t.fn.ajaxForm=function(e){return this.each(function(){t.ajaxForm(this,e)})},t.fn.setInputRequired=function(){return this.each(function(){var e=t(this),i=e.parent();i.is(".input-control,td")?i.addClass("required"):e.is(".chosen")?e.attr("required",null).next(".chosen-container").addClass("required"):i.addClass("required"),e.attr("required",null);var n=i.closest(".input-group");n.length&&1===n.find(".required,input[required],select[required]").length&&n.addClass("required")})},t(function(){t('.form-ajax,form[data-type="ajax"]').ajaxForm(),setTimeout(function(){var i=e.config.requiredFields,n=t("form");i&&(i=i.split(",")),i&&i.length&&t.each(i,function(t,e){n.find("#"+e).attr("required","required")}),n.find("input[required],select[required],textarea[required]").setInputRequired()},400),t('form[target="hiddenwin"]').on("submit",function(){var e=t(this);e.data("zui.ajaxform")||e.enableForm(!1).data("disabledTime",(new Date).getTime())}).on("click",function(){var e=t(this),i=e.data("disabledTime");i&&(new Date).getTime()-i>1e4&&e.enableForm(!0).data("disabledTime",null)})})}(jQuery,window,void 0),function(t){"use strict";var e="zui.searchList",i=function(t,e){if(t&&t.length)for(var i=0;i
    ').append(s)),i.$menu.append(s),i.$menu.removeClass("loading"),i.isLoaded=!0,e&&e(!0)},error:function(){i.$menu.removeClass("loading").append('
    '+(n.errorText||window.lang&&window.lang.timeout)+"
    "),e&&e(!1)}},n.ajax))},n.prototype.scrollTo=function(t){t.length&&t[0].scrollIntoViewIfNeeded&&t[0].scrollIntoViewIfNeeded({behavior:"smooth"})},n.prototype.getItems=function(){return this.$.find(this.options.selector).addClass("search-list-item")},n.prototype.getActiveItem=function(){return this.getItems().filter(".active:first")},n.prototype.search=function(e){var n=this,o=void 0===e||null===e||""===e;n.$.toggleClass("has-search-text",!o);var a=n.getItems().removeClass("active");if(o)a.removeClass("hidden");else{var s=e.trim().split(" ");a.each(function(){var e=t(this),n=(e.text()+" "+(e.data("key")||e.data("filter")||"")).trim();e.toggleClass("hidden",!i(s,n))})}n.scrollTo(a.not(".hidden").first().addClass("active")),n.$.trigger("onSearchComplete",e)},n.DEFAULTS={selector:".list-group a:not(.not-list-item)",searchBox:".search-box",onSelectItem:null},t.fn.searchList=function(i){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof i&&i;a||o.data(e,a=new n(this,s)),"string"==typeof i&&a[i]()})},n.NAME=e,t.fn.searchList.Constructor=n,t(function(){t('[data-ride="searchList"]').searchList()})}(jQuery),function(t){"use strict";var e="zui.labelSelector",i=function(n,o){var a=this;a.name=e,a.$=t(n),o=a.options=t.extend({},i.DEFAULTS,this.$.data(),o),a.$.hide(),a.update()};i.prototype.select=function(t){t+="",this.$wrapper.find(".label.active").removeClass("active"),this.$wrapper.find('.label[data-value="'+t+'"]').addClass("active"),this.$.val(t).trigger("change")},i.prototype.update=function(){var e=this,i=e.options,n=e.$wrapper;if(!n){if(i.wrapper)n=t(i.wrapper);else{var o=e.$.next();n=o.hasClass(".label-selector")?o:t('
    ')}n.parent().length||e.$.after(n),e.$wrapper=n,n.on("click",".label",function(i){var n=e.$.val(),o=t(this).data("value");e.hasEmptyValue!==!1&&o==n&&(o=e.hasEmptyValue),e.select(o),i.preventDefault()})}n.empty();var a=e.$.val();e.hasEmptyValue=!1,e.$.children("option").each(function(){var e=t(this),o={label:e.text(),value:e.val()},s=(""===o.value||"0"===o.value)&&!o.label,r=t(i.labelTemplate||'');i.labelClass&&!s&&r.addClass(i.labelClass),i.labelCreator?r=i.labelCreator(r):(r.data("option",o).attr("data-value",o.value),s?r.addClass("empty").append(''):r.text(o.label).toggleClass("active",a===o.value)),n.append(r)})},i.DEFAULTS={},t.fn.labelSelector=function(n){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof n&&n;a||o.data(e,a=new i(this,s)),"string"==typeof n&&a[n]()})},i.NAME=e,t.fn.labelSelector.Constructor=i,t(function(){t('[data-provide="labelSelector"]').labelSelector()})}(jQuery),function(t){"use strict";var e="zui.fileInput",i=t.BYTE_UNITS={B:1,KB:1024,MB:1048576,GB:1073741824,TB:1099511627776},n=t.formatBytes=function(t,e,n){return void 0===e&&(e=2),n||(n=ts.fileMaxSize&&(c.val(""),(window.bootbox||window).alert(s.fileSizeError.format(n(s.fileMaxSize)))),r.update()}),r.update()};a.prototype.getFile=function(){var t=this.$input.prop("files");return t&&t[0]},a.prototype.update=function(){var t=this,e=t.$,i=t.getFile(),o=!i;e.toggleClass("normal",!o).toggleClass("empty",o),i?(t.oldName=i.name,e.find(".file-title").text(i.name).attr("title",i.name),e.find(".file-size").text(n(i.size)),e.find(".file-editbox").val(i.name).attr("size",i.name.length),t.options.onSelect&&t.options.onSelect(i,t)):e.find(".file-editbox").val("")},a.DEFAULTS={fileMaxSize:0,fileSizeError:"无法上传大于 {0} 的文件。"},t.fn.fileInput=function(i){return this.each(function(){var n=t(this),o=n.data(e),s="object"==typeof i&&i;o||n.data(e,o=new a(this,s)),"string"==typeof i&&o[i]()})},a.NAME=e,t.fn.fileInput.Constructor=a,t(function(){t('[data-provide="fileInput"]').fileInput()});var s="zui.fileInputList",r=function(e,i){var n=this;n.name=s;var o=n.$=t(e);i=n.options=t.extend({},r.DEFAULTS,this.$.data(),i),n.$template=o.find(".file-input").detach(),n.add()};r.prototype.add=function(){var t=this,e=t.options,i=t.$template.clone();"before"===e.appendWay?t.$.prepend(i):t.$.append(i),i.fileInput({fileMaxSize:e.eachFileMaxSize,fileSizeError:e.fileSizeError,onDelete:function(e){e.$.remove(),t.options.onDelete&&t.options.onDelete(e,t)},onSelect:function(e,i){t.add(),t.options.onSelect&&t.options.onSelect(e,i,t)}})},r.DEFAULTS={fileMaxSize:0,eachFileMaxSize:0,appendWay:"after",fileSizeError:"无法上传大于 {0} 的文件。"},t.fn.fileInputList=function(e){return this.each(function(){var i=t(this),n=i.data(s),o="object"==typeof e&&e;n||i.data(s,n=new r(this,o)),"string"==typeof e&&n[e]()})},r.NAME=s,t.fn.fileInputList.Constructor=r,t(function(){t('[data-provide="fileInputList"]').fileInputList()})}(jQuery),function(t){window.config||(window.config={}),t.createLink=window.createLink=function(e,n,o,a,s,r,l){if("object"==typeof e)return t.createLink(e.moduleName,e.methodName,e.vars,e.viewType,e.isOnlyBody,e.hash,e.tid);if(t.tabSession&&!l&&(l=t.tabSession.getTid()),a||(a=config.defaultView),s||(s=!1),o)for("string"==typeof o&&(o=o.split("&")),i=0;i'+d+"")}}t.val()||(time=e(a.format("hh:mm")),time=time-time%10+10,t.val(n(time)))};t.fn.timeSpanControl=function(i){return this.each(function(){var s=t(this),r=t.extend({},i,s.data()),l=s.find('[name="begin"],.control-time-begin'),c=s.find('[name="end"],.control-time-end'),h=function(){var t=l.val();if(s.find(".hide-empty-begin").toggleClass("hide",!t),t){var i=n(e(t)+30);c.find('option[value="'+i+'"]').length&&c.val(i),r.onChange&&r.onChange(c,i)}};if(s.data("timeSpanControlInit")){if(r.begin){var d=o(r.begin).format("hh:mm");l.find('option[value="'+d+'"]').length&&l.val(d),r.onChange&&r.onChange(l,d)}if(r.end){var u=o(r.end).format("hh:mm");c.find('option[value="'+u+'"]').length&&c.val(u),r.onChange&&r.onChange(c,u)}}else l.on("change",h),a(l,r.begin),a(c,r.end),s.data("timeSpanControlInit",!0);r.end||h()})},t.timeSpanControl={convertTimeToNum:e,convertNumToTime:n,initTimeSelect:a,createTime:o};var s=t.setSearchType=function(e,i){var n=t("#searchType");e||(e=n.val()),e=e||"bug",n.val(e);var o=t("#searchTypeMenu");o.find("li.selected").removeClass("selected");var a=o.find('a[data-value="'+e+'"]'),s=a.text();a.parent().addClass("selected"),t("#searchTypeName").text(s),i||t("#searchInput").focus()};t.gotoObject=function(e,i){if(e||(e=t("#searchType").val()),i||(i=t("#searchInput").val()),i&&e)if(i=i.replace(/[^\d]/g,"")){var n=e.split("-");e=n[0];var o=n.length>1?n[1]:"testsuite"===e?"library":"view",a=t.createLink(e,o,"id="+i);t.apps?t.apps.open(a):window.location.href=a}else{var s={zh_cn:"请输入数字ID进行搜索",zh_tw:"請輸入數值ID行搜索"};alert(lang.searchTip||s[t.zui.clientLang()]||"Please enter a numberic id to search")}t("#searchInput").val(i).focus()},t(function(){s(null,!0),t(document).on("keydown",function(e){e.ctrlKey&&71===e.keyCode&&(t("#searchInput").val("").focus(),e.stopPropagation(),e.preventDefault())})}),t.removeAnchor=window.removeAnchor=function(t){var e=t.lastIndexOf("#");return e>-1?t.substr(0,e):t},t.refreshPage=function(t){t?window.top.location.reload():window.location.reload()},t.selectLang=window.selectLang=function(e){t.cookie("lang",e,{expires:config.cookieLife,path:config.webRoot}),t.ajaxSendScore("selectLang"),t.refreshPage(1)},t.selectTheme=window.selectTheme=function(e){t.cookie("theme",e,{expires:config.cookieLife,path:config.webRoot}),t.ajaxSendScore("selectTheme"),t.refreshPage(1)},t.zui.Picker&&(t.extend(t.zui.Picker.DEFAULTS,{optionRender:function(e,i,n){if("user"===n.options.type){var o=n.options.users;if(!o)return;var a=o[i.value];if(!a)return;if(e.find(".picker-option-text").text(a.realname||a.account),e.hasClass("picker-user-option"))return;return e.prepend(t('
    ').avatar({user:a})),a.deptName&&e.append(t('').text(a.deptName)),a.roleName&&e.append(t('').text(a.roleName)),e.addClass("picker-user-option")}},checkable:!0,maxListCount:500,disableScrollOnShow:!1}),t.zui.setUserPickerInfos=function(e){t.zui.Picker.DEFAULTS.users=t.extend({},t.zui.Picker.DEFAULTS.users,e)},t(function(){t(".picker-select[data-pickertype!='remote']").picker({chosenMode:!0}),t("[data-pickertype='remote']").each(function(){var e=t(this).attr("data-pickerremote");t(this).picker({chosenMode:!0,remote:e})}),window.pickerUsers&&t.zui.setUserPickerInfos(window.pickerUsers),t(".user-picker").picker({type:"user"})})),t.chosenDefaultOptions={middle_highlight:!0,disable_search_threshold:1,compact_search:!0,allow_single_deselect:!0,placeholder_text_single:" ",placeholder_text_multiple:" ",search_contains:!0,max_drop_width:500,max_drop_height:245,no_wrap:!0,drop_direction:function(){var e=t(this.container).closest(".table-responsive:not(.scroll-none)");if(e.length){if(this.drop_directionFixed)return this.drop_directionFixed;e.css("position","relative");var i="down",n=this.container.find(".chosen-drop"),o=this.container.position(),a=n.outerHeight();return o.top>=a&&o.top+31+a>e.outerHeight()&&(i="up"),this.drop_directionFixed=i,i}return"auto"}},t.chosenSimpleOptions=t.extend({},t.chosenDefaultOptions,{disable_search_threshold:6}),t.fn._chosen=t.fn.chosen,t.fn.chosen=function(e){return"string"==typeof e?this._chosen(e):this.each(function(){var i=t(this).addClass("chosen-controled");return i._chosen(t.extend({},i.hasClass("chosen-simple")?t.chosenSimpleOptions:t.chosenDefaultOptions,i.data(),e))})},t.fn.chosen.Constructor=t.fn._chosen.Constructor,t(function(){t(".chosen,.chosen-simple").each(function(){var e=t(this);e.closest(".template").length||e.chosen()})}),t.extend(t.fn.pager.Constructor.DEFAULTS,{maxNavCount:8,prevIcon:"icon-angle-left",nextIcon:"icon-angle-right",firstIcon:"icon-first-page",lastIcon:"icon-last-page",navEllipsisItem:"…",menuDirection:"dropup",pageSizeOptions:[5,10,15,20,25,30,35,40,45,50,100,200,500,1e3,2e3],elements:["total_text","size_menu","first_icon","prev_icon",'
    {page}/{totalPage}
    ',"next_icon","last_icon"],onPageChange:function(e,i){e.recPerPage!==i.recPerPage&&t.cookie(this.options.pageCookie,e.recPerPage,{expires:config.cookieLife,path:config.webRoot}),e.recPerPage!==i.recPerPage&&(window.location.href=this.createLink())}}),t.extend(!0,t.zui.Messager.DEFAULTS,{cssClass:"messagger-zt",icons:{success:"check-circle",info:"chat-line",warning:"exclamation-sign",danger:"exclamation-sign"}}),t.fn.reverseOrder=function(){return this.each(function(){var e=t(this);e.prependTo(e.parent())})};var r=function(e,i){var n=t(e);if(!n.data("historiesInited")){n.data("historiesInited",1),i=t.extend({},n.data(),i);var o=n.find(".histories-list"),a=!0,s=!1;n.on("click",".btn-reverse",function(){o.children("li").reverseOrder(),a=!a,t(this).find(".icon").toggleClass("icon-arrow-up",a).toggleClass("icon-arrow-down",!a);var e="#lastComment",i=t(e);i.length&&window.KindEditor&&(window.KindEditor.remove(e),i.kindeditor())}).on("click",".btn-expand-all",function(){var e=t(this).find(".icon");s=!s,e.toggleClass("icon-plus",!s).toggleClass("icon-minus",s),o.children("li").toggleClass("show-changes",s)}).on("click",".btn-expand",function(){t(this).closest("li").toggleClass("show-changes")}).on("click",".btn-strip",function(){var e=t(this),n=e.find(".icon"),o=n.hasClass("icon-code");n.toggleClass("icon-code",!o).toggleClass("icon-text",o),e.attr("title",o?i.original:i.textdiff),e.closest("li").toggleClass("show-original",o)}),o.find(".btn-strip").attr("title",i.original);var r=n.find(".modal-comment").modal({show:!1}).on("shown.zui.modal",function(){var t=r.find("#comment");t.length&&(t.focus(),window.editor&&window.editor.comment&&window.editor.comment.focus())}).on("show.zui.modal",function(){var e=r.find("#comment");e.length&&!e.data("keditor")&&t.fn.kindeditor&&e.kindeditor()});n.on("click",".btn-comment",function(t){r.modal("toggle"),t.preventDefault()}).on("click",".btn-edit-comment,.btn-hide-form",function(){t(this).closest("li").toggleClass("show-form")});var l=n.find(".comment-edit-form");l.ajaxForm({success:function(t,e,i,n){setTimeout(function(){l.closest("li").removeClass("show-form")},2e3)}})}};t.fn.histories=function(t){return this.each(function(){r(this,t)})},t(function(){t(".histories").histories()});var l=0,c=0;t.toggleSidebar=function(e){var i=t("#sidebar");if(i.length){var n=t("main");if(void 0===e)e=n.hasClass("hide-sidebar");else if(e&&!n.hasClass("hide-sidebar"))return;n.toggleClass("hide-sidebar",!e),clearTimeout(l),t.zui.store.set(c,e);var o=i.children(".cell"),a={overflow:"visible",maxHeight:"initial"};e?(i.addClass("showing"),l=setTimeout(function(){i.removeClass("showing"),i.trigger("sidebar.toggle",e)},210)):(i.trigger("sidebar.toggle",e),t(window).width()<1900&&(a={overflow:"hidden",maxHeight:t(window).height()-45})),o.css(a)}};var h=t.initSidebar=function(){var e=t("#sidebar");if(e.length){if(e.data("init"))return!0;c="sidebar:"+(e.data("id")||config.currentModule+"/"+config.currentMethod);var i=t("main");if(i.length){i.on("click",".sidebar-toggle",function(){t.toggleSidebar(i.hasClass("hide-sidebar"))});var n=t.zui.store.get(c,e.data("hide")!==!1);n===!1&&e.addClass("no-animate"),t.toggleSidebar(n),n===!1&&setTimeout(function(){e.removeClass("no-animate")},500);var o=e.find(".sidebar-toggle");if(o.length){var a=function(){var e=o[0].getBoundingClientRect(),i=t(window).height(),n=Math.max(0,Math.floor(Math.min(i-40,e.top+e.height)-Math.max(e.top,0))/2)+(e.top<0?0-e.top:0);o.removeClass("fade").find(".icon").css("top",n+(t.zui.browser.isIE()?(i-80)/2:0))};a(),e.data("init",1).on("sidebar.toggle",a);var s=t.zui.browser.isIE()?1500:0,r=0,l=null,h=function(){var t=Date.now();return l&&(clearTimeout(l),l=null),t-rtr input[type="checkbox"]:checked');i.each(function(){var i=parseInt(t(this).val(),10);NaN!==i&&e.push(i)}),t.cookie("checkedItem",e.join(","),{expires:config.cookieLife,path:config.webRoot})},t.extend(t.fn.modal.bs.Constructor.DEFAULTS,{scrollInside:!0,backdrop:"static",headerHeight:100}),t.extend(t.zui.ModalTrigger.DEFAULTS,{scrollInside:!0,backdrop:"static"}),t.fn.initIframeModal=function(){return this.each(function(){var e=t(this);if(!e.parents('[data-ride="table"],.skip-iframe-modal').length){var i={type:"iframe"};e.hasClass("export")&&t.extend(i,{width:800,shown:setCheckedCookie},e.data()),e.modalTrigger(i)}})},t(function(){t("a.iframe,.export").initIframeModal()}),t.fixedTableHead=window.fixedTableHead=function(e,i){var n=t(e);if(n.is("table")||(n=n.find("table")),n.length){var o=t(i||window),a=null,s=function(){var e=n.children("thead"),i=e[0].getBoundingClientRect(),o=n.next(".fixed-head-table");if(i.top<0){var s=e.width();if(o.length){if(a!==s){a=s;var r=o.find("th");e.find("th").each(function(e){r.eq(e).width(t(this).width())})}}else{var o=t("
    ").addClass(n.attr("class")),l=e.clone(),r=l.find("th");e.find("th").each(function(e){r.eq(e).width(t(this).width())}),o.append(l).insertAfter(n)}o.css({left:i.left,width:i.width}).show()}else o.hide()};o.on("scroll",s).on("resize",s),s()}},t(document).on("click","tr[data-url]",function(){var e=t(this),i=e.data("href")||e.data("url");i&&(window.location.href=i)}),"yes"===config.onlybody&&self===parent&&(window.location.href=window.location.href.replace("?onlybody=yes","").replace("&onlybody=yes","")),t(function(){t("body").addClass("m-{currentModule}-{currentMethod}".format(config))});var d,u,p,f,g,m=function(){d||(d=t("#subNavbar"),u=t("#pageNav"),p=t("#pageActions"),f=d.children(".nav"),g=f.outerWidth());var e=d.outerWidth(),i=u.outerWidth()||0,n=p.outerWidth()||0;if(i=i?i+15:0,n=n?n+15:0,!i&&!n)return void f.css({maxWidth:null,left:null,position:"static"});var o=Math.max(300,e-i-n),a=Math.min(o,g),s=(e-a)/2,r=i&&s.btn-toolbar");if(e.length){var i,n,o=e.children(),a=o.length,s=!1,r=null;if(a)for(o.each(function(e){i=t(this),n=i.is(".divider"),n&&!r&&i.hide(),s||n||(s=!0),r=n?null:i,!n||e!==a-1&&0!==e||i.hide()});i.length&&i.is(".divider");)i=i.hide().prev();s||e.hide()}};t(function(){t(".input-group,.btn-group").fixInputGroup(),x()}),window.holders&&t.each(window.holders,function(e){var i=t("#"+e);i.length&&i.is("input")&&i.attr("placeholder",window.holders[e])}),t(function(){var e=t(".table-responsive"),i=t.fixTableResponsive=function(){e.each(function(){this.scrollHeight-3<=this.clientHeight&&this.scrollWidth-3<=this.clientWidth?t(this).addClass("scroll-none").css("overflow","visible"):t(this).removeClass("scroll-none").css("overflow","auto")})};e.length&&(t(window).on("resize",i),setTimeout(i,100))});var C=function(){var e=this,i=t(e),n=i.closest("tr").find("textarea");if(n.length){var o=32;n.each(function(){var e=t(this).closest("td"),i=e.css("height");e.css("height",this.style.height),this.style.height="auto"; -var n=this.value?this.scrollHeight+2:32;o=Math.max(o,n),e.css("height",i)}),n.css("height",o)}else{e.style.height="auto";var a=e.value?e.scrollHeight+2:32;e.style.height=a+"px"}};t.autoResizeTextarea=function(e){t(e).each(C)},t(function(){t("textarea.autosize").each(C),t(document).on("input paste change","textarea.autosize",C)}),t(function(){var e=t("#dropMenu,.drop-menu");e.length&&e.on("click",".toggle-right-col",function(e){t(this).closest("#dropMenu,.drop-menu").toggleClass("show-right-col"),e.stopPropagation(),e.preventDefault()})});var _="undefined"!=typeof InstallTrigger;t.zui.browser.firefox=_,t("html").toggleClass("is-firefox",_).toggleClass("not-firefox",!_),t(function(){var e=t("#mainContent>.main-col"),i=e.children(".main-actions");if(i.length){var n=i.prev();if(i.length&&n.length){t('
    ').css("height",i.outerHeight()).insertAfter(i);var o=0,a=function(){var e=n[0].getBoundingClientRect(),s=e.top+e.height+120>t(window).height();if(t("body").toggleClass("main-actions-fixed",s),s){var r=n.width();r?i.width(r):o<10&&setTimeout(a,1e3)}o++};t.resetToolbarPosition=a,a(),t(window).on("resize scroll",a)}}}),t(document).on("show.zui.modal",function(e){t("body.body-modal").length&&window.parent&&window.parent!==window&&t(e.target).is(".modal")&&window.parent.$("body").addClass("hide-modal-close")}).on("hidden.zui.modal",function(e){t("body.body-modal").length&&window.parent&&window.parent!==window&&window.parent.$("body").removeClass("hide-modal-close")}).on("loaded.zui.modal",function(e){t("body").removeClass("hide-modal-close")}),t(function(){var e=t(".dropdown-menu.with-search");e.length&&(e.find(".menu-search").on("click",function(t){return t.stopPropagation(),!1}),e.on("keyup change paste","input",function(){var e=t(this),i=e.closest(".dropdown-menu.with-search"),n=e.val().toLowerCase(),o=i.find(".option");""==n?o.removeClass("hide"):o.each(function(){var e=t(this);e.toggleClass("hide",e.text().toString().toLowerCase().indexOf(n)<0&&e.data("key").toString().toLowerCase().indexOf(n)<0)})}),e.parents(".dropdown-submenu").one("mouseenter",function(){var e=t(this).find(".dropdown-list")[0];e&&e.getBoundingClientRect&&setTimeout(function(){var i=270,n=e.getBoundingClientRect();n.top<0&&(i=Math.min(270,n.height)+n.top),e.style.maxHeight=Math.min(270,i,t(window).height()-28)+"px"},50)})),t(".dropdown-menu.with-search .menu-search").on("click",function(t){return t.stopPropagation(),!1})})}(jQuery),function(t){function e(){if(!config.skipRedirect&&!window.skipRedirect){var e=window.parent,i=config.currentModule,n=config.currentMethod,o="index"===i&&"index"===n,a="#_single"===location.hash||/(\?|\&)_single/.test(location.search)||o||!t("#mainHeader,#editorNav").length||"tutorial"===i||"install"===i||"upgrade"===i||"user"===i&&("login"===n||"deny"===n)||"my"===i&&"changepassword"===n||t("body").hasClass("allow-self-open"),s=location.href;if(e===window&&!a){var r=location.pathname+location.search+location.hash;return void(location.href=t.createLink("index","index","")+"#app="+encodeURIComponent(r))}if(e!==window&&e.$.apps){o&&e.location.reload();var l=window.name;if(0===l.indexOf("app-")){t.apps=window.apps=e.$.apps;var c=l.substring(4);t.appCode=c,t(document).on("click",function(t){var i=e.document.getElementById(window.name);if(i){var n=e.document.getElementById(i.name)||i;if(n){var o;"function"==typeof Event?o=new Event(t.type,{bubbles:!0}):(o=document.createEvent("Event"),o.initEvent(t.type,!0,!0)),n.dispatchEvent(o)}}}).on("click","a,.open-in-app,.show-in-app",function(e){var i=t(this);if(!i.is("[data-modal],[data-toggle],[data-ride],[data-tab],.iframe,.not-in-app,[target]")&&!i.data("zui.modaltrigger")){var n=i.hasClass("show-in-app")?"":i.attr("href")||(i.is("a")?"":i.data("url")),o=i.data("app")||i.data("group");if(n){if(0===n.indexOf("javascript:")||"#"===n[0])return;var a=t.parseLink(n);if(a.external)return;if("index"===a.moduleName&&"index"===a.methodName)return window.location.reload(),void e.preventDefault()}else if(!o)return;o||(o=t.apps.getAppCode(n)),o&&("help"===o&&(t.apps.appsMap.help.text=i.text(),t.apps.appsMap.help.url||(t.apps.appsMap.help.url=n)),t.apps.open(n,o)&&e.preventDefault())}}),t.apps.updateUrl(c,s,document.title)}}}}function i(){var e=t("#navbar>.nav");if(e.length){var i=t("#heading"),n=+i.css("left").replace("px",""),o=i.outerWidth(),a=e.width(),s=t("#mainHeader>.container").width()-2*n,r=Math.floor((s-a)/2);e.css("marginLeft",r>>0;if(0===o)return!1;for(var a=0|e,s=Math.max(a>=0?a:o-Math.abs(a),0);s1&&("?"===e[0]&&(e=e.substr(1)),e.split("&").forEach(function(t){var e=t.split("=",2);if(e.length>1)try{i[e[0]]=decodeURIComponent(e[1])}catch(n){i[e[0]]=""}else i[e[0]]=""})),t?i[t]:i},t.parseLink=function(e){if(!e)return{};var i=0===e.indexOf("http:")||0===e.indexOf("https:");if(i){var n=window.location.origin;if(e.indexOf(n)<0)return{external:!0,url:e};e=e.substr((n+config.webRoot).length)}var o=e.split("#"),a=o[0].split("?"),s=a[1],r=s?t.getSearchParam("",s):{},l=a[0],c={url:e,isOnlyBody:"yes"===r.onlybody,vars:[],hash:o[1]||"",params:r,tid:r.tid||""};if("GET"===config.requestType){c.moduleName=r[config.moduleVar]||"index",c.methodName=r[config.methodVar]||"index",c.viewType=r[config.viewVar]||config.defaultView;for(var h in r)h!==config.moduleVar&&h!==config.methodVar&&h!==config.viewVar&&"onlybody"!==h&&"tid"!==h&&c.vars.push([h,r[h]])}else{var d=l.lastIndexOf("/");d===l.length-1&&(l=l.substr(0,d),d=l.lastIndexOf("/")),d>=0&&(l=l.substr(d+1));var u=l.lastIndexOf(".");u>=0?(c.viewType=l.substr(u+1),l=l.substr(0,u)):c.viewType=config.defaultView;var p=l.split(config.requestFix);if(c.moduleName=p[0]||"index",c.methodName=p[1]||"index",p.length>2)for(var f=2;f.nav>li").length>10&&(i(),t(window).on("resize",i)),setTimeout(n,1e3)})}(jQuery),function(t){"use strict";function e(e,i){"object"!=typeof i&&(i={user:i});var n=t(e);i=t.extend({},n.data(),i);var o=i.user;"string"==typeof o&&(o={account:o});var a={},s=i.size;s&&(a.width=s,a.height=s,a.lineHeight=s,Number.isNaN(+s)||n.addClass("size-"+s));var r=!!o.avatar;if(n.toggleClass("has-image",r).toggleClass("has-text",!r),n.empty(),r)n.append(t("").attr("src",o.avatar));else{var l=t.zui.strCode(o.account)*(i.hueDistance||43)%360;a.background="hsl("+l+","+(i.saturation||"40%")+","+(i.lightness||"60%")+")",Number.isNaN(+s)||(a.fontSize=Math.round(s/2)+"px");var c=o.name||o.realname||o.account;c=/^[\u4e00-\u9fa5\s]+$/.test(c)?c.length<=2?c:c.substring(c.length-2):/^[A-Za-z\d\s]+$/.test(c)?c[0].toUpperCase():c.length<=2?c:c.substring(0,2),n.append(t('').text(c))}return n.css(a)}t.fn.avatar=function(t){return this.each(function(){e(this,t)})}}(jQuery),$.zui.lang("de",{"zui.pager":{pageOfText:"Seite {0}",prev:"Zurück",next:"Nächste Seite",first:"Erste Seite",last:"Letzte Seite","goto":"Goto",pageOf:"Seite {page}",totalPage:"{totalPage} Seiten",totalCount:"Total: {recTotal} Artikel",pageSize:"{recPerPage} Artikel pro Seite",itemsRange:"Seiten {start} bis {end}",pageOfTotal:"Seite {page}/{totalPage}"},"zui.boards":{append2end:"Gehen Sie zum Ende"},"zui.browser":{tip:"Online. Sorgenfrei. Aktualisiere deinen Browser noch heute!"},"zui.calendar":{weekNames:["Son","Mon","Die","Mit","Don","Fri","Sam"],monthNames:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",year:"{0}Jahr",month:"{0}Monat",yearMonth:"{0}-{1}"},"zui.chosenIcons":{emptyIcon:"[Kein Icon]",commonIcons:"Gemeinsame Symbole",webIcons:"Web-Symbol",editorIcons:"Editor-Symbol",directionalIcons:"Pfeil Zusammenfluss",otherIcons:"Andere Symbole"},"zui.colorPicker":{errorTip:"Kein gültiger Farbwert"},"zui.datagrid":{errorCannotGetDataFromRemote:"Daten vom Remote-Server ({0}) können nicht abgerufen werden.",errorCannotHandleRemoteData:"Die vom Remote-Server zurückgegebenen Daten können nicht verarbeitet werden."},"zui.guideViewer":{prevStep:"Vorheriger Schritt",nextStep:"Nächster Schritt"},"zui.tabs":{reload:"Neu laden",close:"Schliessen",closeOthers:"Schließen Sie andere Registerkarten",closeRight:"Schließen Sie die rechte Registerkarte",reopenLast:"Letzten geschlossenen Tab wiederherstellen",errorCannotFetchFromRemote:"Inhalt kann nicht vom Remote-Server abgerufen werden ({0})."},"zui.uploader":{},datetimepicker:{days:["Sonntag","Montag","Diensteg","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["Son","Mon","Die","Mit","Don","Fri","Sam"],daysMin:["Son","Mon","Die","Mit","Don","Fri","Sam"],months:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",suffix:[],meridiem:[]},chosen:{no_results_text:"Nicht gefunden"},bootbox:{OK:"OK",CANCEL:"Stornieren",CONFIRM:"Bestätigen"}}),$.zui.lang("fr",{"zui.pager":{pageOfText:"Page {0}",prev:"Prev",next:"Suivant",first:"First",last:"Last","goto":"Goto",pageOf:"Page {page}",totalPage:"{totalPage} pages",totalCount:"Total: {recTotal} items",pageSize:"{recPerPage} per page",itemsRange:"De {start} à {end}",pageOfTotal:"Page {page} de {totalPage}"},"zui.boards":{append2end:"Aller jusqu'au bout"},"zui.browser":{tip:"Naviguez sans crainte sur Internet. Mettez votre navigateur à jour dès aujourd'hui!"},"zui.calendar":{weekNames:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],monthNames:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Août","Sep","Oct","Nov","Déc"],today:"Aujourd'hui",year:"{0} Année",month:"{0} Mois",yearMonth:"{0}-{1}"},"zui.chosenIcons":{emptyIcon:"[Aucune icône]",commonIcons:"Icônes communes",webIcons:"Icône Web",editorIcons:"Icône de l'éditeur",directionalIcons:"Flèche confluence",otherIcons:"Autres icônes"},"zui.colorPicker":{errorTip:"Pas une valeur de couleur valide"},"zui.datagrid":{errorCannotGetDataFromRemote:"Impossible d'obtenir les données du serveur distant ({0}).",errorCannotHandleRemoteData:"Impossible de traiter les données renvoyées par le serveur distant."},"zui.guideViewer":{prevStep:"Étape précédente",nextStep:"Prochaine étape"},"zui.tabs":{reload:"Recharger",close:"Fermer",closeOthers:"Fermez les autres onglets",closeRight:"Fermer l'onglet de droite",reopenLast:"Restaurer le dernier onglet fermé",errorCannotFetchFromRemote:"Impossible d'obtenir le contenu du serveur distant ({0})."},"zui.uploader":{},datetimepicker:{days:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],daysShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],daysMin:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],months:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Août","Sep","Oct","Nov","Déc"],monthsShort:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Août","Sep","Oct","Nov","Déc"],today:"Aujourd'hui",suffix:[],meridiem:[]},chosen:{no_results_text:"Pas trouvé"},bootbox:{OK:"D'accord",CANCEL:"Annuler",CONFIRM:"Confirmer"}}); \ No newline at end of file +function(t){function e(e){if("string"==typeof e.data){var i=e.handler,n=e.data.toLowerCase().split(" ");e.handler=function(e){if(this===e.target||!/textarea|select/i.test(e.target.nodeName)&&"text"!==e.target.type){var o="keypress"!==e.type&&t.hotkeys.specialKeys[e.which],a=String.fromCharCode(e.which).toLowerCase(),s="",r={};e.altKey&&"alt"!==o&&(s+="alt+"),e.ctrlKey&&"ctrl"!==o&&(s+="ctrl+"),e.metaKey&&!e.ctrlKey&&"meta"!==o&&(s+="meta+"),e.shiftKey&&"shift"!==o&&(s+="shift+"),o?r[s+o]=!0:(r[s+a]=!0,r[s+t.hotkeys.shiftNums[a]]=!0,"shift+"===s&&(r[t.hotkeys.shiftNums[a]]=!0));for(var l=0,c=n.length;l","/":"?","\\":"|"}},t.each(["keydown","keyup","keypress"],function(){t.event.special[this]={add:e}})}(jQuery),function(t,e,i){"use strict";var n="zui.picker",o={},a={lang:null,remote:null,remoteConverter:null,remoteOnly:!1,onRemoteError:null,disableEmptySearch:!1,textKey:"text",valueKey:"value",keysKey:"keys",multi:"auto",formItem:"auto",list:null,allowSingleDeselect:null,autoSelectFirst:!1,maxSelectedCount:0,maxListCount:50,hideEmptyTextOption:!0,searchValueKey:!0,emptyResultHint:null,hideOnScroll:!0,inheritFormItemClasses:!1,emptySearchResultHint:null,accurateSearchHint:null,remoteErrorHint:null,deleteByBackspace:!0,disableScrollOnShow:!0,maxDropHeight:250,dropDirection:"auto",dropWidth:"100%",maxAutoDropWidth:450,multiValueSplitter:",",multiSelectActions:5,searchDelay:200,autoClearDrop:6e4,fixLabelFor:!0,hotkey:!0,onSelect:null,onDeselect:null,onBeforeChange:null,onChange:null,onReady:null,onNoResults:null,onShowingDrop:null,onHidingDrop:null,onShowedDrop:null,onHiddenDrop:null,valueMustInList:!0},s={zh_cn:{emptyResultHint:"没有可选项",emptySearchResultHint:"没有找到 “{0}”",accurateSearchHint:"请提供更多关键词缩小匹配范围",remoteErrorHint:"无法从服务器获取结果 - {0}",selectAll:"全选",deselectAll:"取消选择"},zh_tw:{emptyResultHint:"沒有可選項",emptySearchResultHint:"沒有找到 “{0}”",accurateSearchHint:"請提供更多關鍵詞縮小匹配範圍",remoteErrorHint:"無法從服務器獲取結果 - {0}",selectAll:"全選",deselectAll:"取消選擇"},en:{emptyResultHint:"No options",emptySearchResultHint:'Cannot found "{0}"',accurateSearchHint:"Suggest to provide more keywords",remoteErrorHint:"Unable to get result from server: {0}",selectAll:"Select all",deselectAll:"Deselect all"}},r=function(o,a){var l=this;l.name=n,l.$=t(o),l.id="pk_"+(l.$.attr("id")||t.zui.uuid()),a=l.options=t.extend({},r.DEFAULTS,this.$.data(),a),void 0!==a.hideOnWindowScroll&&(a.hideOnScroll=a.hideOnWindowScroll);var c=t.zui.clientLang?t.zui.clientLang():"en",h=a.lang||c;l.lang=t.zui.getLangData?t.zui.getLangData(n,h,s):s[h]||s[c];var d,u,p=a.formItem,f='.form-item,input[type="hidden"],select,input[type="text"]';if(d="self"===p?l.$:"auto"!==p&&p?l.$.find(p):l.$.is(f)?l.$:l.$.find(f).first(),!d.length)return console.error&&console.error("Cannot found form item for picker.");if(d.is('input[type="hidden"]'))u="hidden";else if(d.is("select"))u="select";else{if(!d.is('input[type="text"]'))return console.error&&console.error("Unknown form type for picker.");u="text"}a.inheritFormItemClasses&&v.addClass(d.attr("class")),l.formType=u,l.$formItem=d.removeClass("picker").hide(),l.selfFormItem=d.is(l.$);var g=a.multi;g&&"auto"!==g||(g="select"===u&&"multiple"===d.attr("multiple")),g=!!g,l.multi=g;var m=a.list;m?l.setList("function"==typeof m?m({search:l.search,limit:a.maxListCount}):m,!0):"select"===u?l.updateFromSelect():l.setList([],!0);var v;v=!l.selfFormItem&&l.$.hasClass("picker")?l.$:t('
    ').insertAfter(l.$),v.addClass("picker").toggleClass("picker-multi",g).toggleClass("picker-single",!g);var y=v.children(".picker-selections");y.length?y.empty():y=t('
    ');var b=l.id+"-search",w=t('').appendTo(y);if(!g){var x=t('
    ');a.allowSingleDeselect&&x.append(''),x.appendTo(y),l.$singleSelection=x}v.toggleClass("picker-input-empty",!w.val().length).append(y),l.$container=v,l.$selections=y,l.$search=w,l.search="";var C=a.placeholder;if(void 0===C&&(C=d.attr("placeholder")),"string"==typeof C&&C.length&&y.append(t('
    ').text(C)),a.placeholder=C,a.fixLabelFor){var _=d.attr("id");_&&t('label[for="'+_+'"]').attr("for",b)}var k=void 0!==a.defaultValue?a.defaultValue:d.val();if(l.setValue(k,!0),w.on("focus",function(){l._blurTimer&&(clearTimeout(l._blurTimer),l._blurTimer=0),v.addClass("picker-focus"),l.showDropList()}).on("blur",function(){l._blurTimer&&clearTimeout(l._blurTimer),l._blurTimer=setTimeout(function(){l._blurTimer=0,w.is(":focus")||v.removeClass("picker-focus")},100)}).on("input change",function(){var t=w.val();g&&w.width(14*t.length),v.toggleClass("picker-input-empty",!t.length),l.tryUpdateList(t)}),a.hotkey&&w.on("keydown",function(t){var e=t.key||t.which;if(l.dropListShowed){var i=l.activeValue,n="string"==typeof i;if("Enter"===e||13===e)n&&(l.select(i,g),g?(l.$search.val(""),l.tryUpdateList("")):w.blur(),t.preventDefault());else if("ArrowDown"===e||40===e){var o,s=l.$activeOption;if(s&&(o=s.next(".picker-option"),g))for(;o.length&&o.hasClass("picker-option-selected");)o=o.next(".picker-option");o&&o.length||(o=l.$optionsList.children(g?".picker-option:not(.picker-option-selected)":".picker-option").first()),o.length&&l.activeOption(o),t.preventDefault()}else if("ArrowUp"===e||30===e){var r,s=l.$activeOption;if(s&&(r=s.prev(".picker-option"),g))for(;r.length&&r.hasClass("picker-option-selected");)r=r.prev(".picker-option");r&&r.length||(r=l.$optionsList.children(g?".picker-option:not(.picker-option-selected)":".picker-option").last()),r.length&&l.activeOption(r),t.preventDefault()}else"Escape"===e||27===e?l.hideDropList(!0):a.deleteByBackspace&&g&&("Backspace"===e||8===e)&&l.value&&l.value.length&&!w.val().length&&l.deselect(l.value[l.value.length-1])}}),g){y.on("mousedown",function(t){if(l.dropListShowed)return t.preventDefault(),void t.stopPropagation()}).on("mouseup",function(e){y.hasClass("sortable-sorting")||t(e.target).closest(".picker-selection-remove").length||l.dropListShowed||l.focus()});var T=a.sortValuesByDnd;if(T&&t.fn.sortable){v.addClass("picker-sortable");var S={selector:".picker-selection",stopPropagation:!0,start:function(){l.hideDropList(!0)},finish:function(e){var i=[];t.each(e.list,function(t,e){i.push(e.item.data("value"))}),l.setValue(i.slice(),!1,!0)}};"object"==typeof T&&t.extend(S,T),y.sortable(S)}}if(y.on("click",".picker-selection-remove",function(e){if(l.multi){var i=t(this).closest(".picker-selection");l.deselect(i.data("value"))}else l.deselect();e.stopPropagation()}),d.on("chosen:updated",function(){l.updateFromSelect(),l.setValue(d.val(),!0),l.updateList()}).on("chosen:activate",l.focus).on("chosen:open",l.showDropList).on("chosen:close",l.hideDropList),v.addClass("picker-ready"),t.zui.asap(function(){l.triggerEvent("ready",{picker:l},"","chosen:ready")}),!a.disableScrollOnShow){var D=a.hideOnScroll;D&&![e,i,!0].includes(D)&&t(D).on("scroll",this.handleParentScroll.bind(this))}};r.prototype.destroy=function(){var e=this,i=e.options;e.hideDropList(!0);var o=e.$search;o.off("focus blur input change"),i.hotkey&&o.off("keydown"),o.remove();var a=e.$selections;a.off("click"),e.multi&&a.off("mousedown mouseup"),a.remove();var s=e.$formItem;e.selectOptionsBackup&&(s.empty(),t.each(e.selectOptionsBackup,function(e,n){var o={value:n[i.valueKey]},a=n[i.keysKey];void 0!==a&&(o["data-"+i.keysKey]=a),s.append(t("
    ");i.$.addClass("load-indicator loading"),s.load(window.location.href+" #"+o,function(r){if(a===o)i.$.empty().html(s.children().html()),i.$.find('[data-ride="pager"]').pager();else{i.$.find("#"+o).empty().html(s.children().html());try{var l=t(r),c=l.find("#"+o).closest('[data-ride="table"],#'+a);if(c.length){var h=c.find(".table-statistic");h.length&&(i.defaultStatistic=h.html());var d=i.$.find('[data-ride="pager"]').data("zui.pager"),u=c.find('[data-ride="pager"]');d&&u.length&&d.set(u.data())}}catch(p){console.error(p)}}i.$.removeClass("load-indicator loading").trigger("beforeTableReload"),delete i.defaultStatistic,i.updateStatistic(),i.initModals(),i.$.datepickerAll();var f=i.$.find("tbody>tr"),g=!1;t.each(i.checkItems,function(t,e){e&&(i.checkRow(f.filter('[data-id="'+t+'"]'),!0,!0),g=!0)}),g&&i.updateCheckUI(),n.nested&&i.initNestedList(),i.$.trigger("tableReload");var m=t("#mainMenu>.btn-toolbar>.btn-active-text>.label");if(m.length){var u=i.$.find(".pager[data-rec-total]"),v=u.length?u.attr("data-rec-total"):i.getTable().find("tbody:first>tr:not(.table-children)").length;m.text(v)}e&&e(),n.afterReload&&n.afterReload()})},r.prototype.initModals=function(){var e=this,i=e.options,n=e.$.find(i.iframeModalTrigger);if(n.length){var o={type:"iframe",onHide:i.replaceId?function(){var n=t.cookie("selfClose");(1==n||i.hot)&&(t("#triggerModal").data("cancel-reload",1),e.reload(function(){t.cookie("selfClose",0)}))}:null};n.modalTrigger(o)}},r.prototype.getTable=function(){var t=this.$;if(this.isDataTable)return t.find("div.datatable");var e=t.is("table")?t:t.find("table:not(.fixed-header-copy)").first();return e.is(".datatable")&&(this.isDataTable=!0,e.data("zui.datatable")||window.initDatatable(e),e=t.find("div.datatable")),e},r.prototype.toggleGroups=function(e){var i=this,n={};i.$.find("tbody>tr").each(function(){var o=t(this).closest("tr").data("id");n[o]||i.toggleRowGroup(o,e)})},r.prototype.toggleRowGroup=function(i,n){var o=this.$.find('tbody>tr[data-id="'+i+'"]'),a=o.filter(".group-summary"),s=n===e?!a.hasClass("hidden"):!!n;o.not(".group-summary").toggleClass("hidden",!s),a.toggleClass("hidden",s),t("body").toggleClass("table-group-collapsed",!this.$.find("tbody>tr.group-summary.hidden").length)},r.prototype.updateStatistic=function(){var i=this,n=i.$.find(".table-statistic");if(n.length){if(i.defaultStatistic===e&&(i.defaultStatistic=n.html()),i.options.statisticCreator)return void n.html(i.options.statisticCreator(i)||i.defaultStatistic);var o=i.statisticCols;if(!o&&o!==!1){o={};var a=!1;i.getTable().find("thead th").each(function(e){var i=t(this),n=i.data("statistic");n&&(a=!0,o[e]={format:n,name:i.text()})}),i.statisticCols=!!a&&o}var s=0;o&&t.each(o,function(t){o[t].total=0,o[t].checkedTotal=0}),i.$.find(i.isDataTable?".fixed-left tbody>tr":"tbody>tr").each(function(){var e=t(this),i=e.hasClass("checked"),n=e.children("td");i&&s++,o&&t.each(o,function(t){var e=parseFloat(n.eq(t).text());isNaN(e)&&(e=0),o[t].total+=e,i&&(o[t].checkedTotal+=e)})});var r=[];if(s)r.push(i.lang.selectedItems.format(s));else if(i.defaultStatistic)return void n.html(i.defaultStatistic);o&&t.each(o,function(t){var e=o[t],n=e[s?"checkedTotal":"total"];e.format&&(n=e.format.format(n)),r.push(i.lang.attrTotal.format(e.name,n))}),n.html(r.join(", "))}},r.prototype.updateFixUI=function(e){var i=this,n=(new Date).getTime();if(!e&&(i.lastUpdateCall&&clearTimeout(i.lastUpdateCall),!i.lastUpdateTime||n-i.lastUpdateTime
    ').append(t('
    ').addClass(i.attr("class")).append(n.clone())).insertAfter(i)),h){var d=c[0].getBoundingClientRect();l.css({left:d.left,width:c.width(),overflow:"hidden"}),l.find(".fixed-header-copy").css({left:o.left-d.left,position:"relative",minWidth:i.width()}),a||c.data("fixHeaderScroll")||(c.data("fixHeaderScroll",1),i.width()>c.width()&&c.on("scroll",function(){e.fixHeader()}))}else l.css({left:o.left,width:o.width});var u=l.find("th");n.find("th").each(function(e){u.eq(e).css("width",t(this).outerWidth())})}else l.remove()},r.prototype.fixFooter=function(){var e,i=this,n=i.getTable(),o=i.$.find(".table-footer");if(i.isDataTable)e=n[0].getBoundingClientRect();else{var a=n.find("tbody");if(!a.length)return;e=a[0].getBoundingClientRect()}var s=i.options.fixFooter;o.toggleClass("fixed-footer",!!r);var r="function"==typeof s?s(e,o):e.bottom>window.innerHeight-50-("number"==typeof s?s:i.pageFooterHeight||5);o.toggleClass("fixed-footer",!!r),n.toggleClass("with-footer-fixed",!!r),n.trigger("fixFooter",r);var l=t("body"),c=l.hasClass("body-modal");if(r){var h=n.parent(),d=h.is(".table-responsive");o.css({bottom:i.pageFooterHeight||0,left:d?h[0].getBoundingClientRect().left:e.left,width:d?h.width():e.width}),c&&l.css("padding-bottom",40)}else o.css({width:"",left:0,bottom:0}),c&&l.css("padding-bottom",0)},r.prototype.checkAll=function(e){var i=this,n=i.$.find(i.isDataTable?".fixed-left tbody>tr":"tbody>tr");n.each(function(){i.checkRow(t(this),e,!0)}),i.updateCheckUI()},r.prototype.checkRow=function(i,n,o){var a=this,s=a.getTable();a.isDataTable&&!i.is(".datatable-row-left")&&(i=s.find('.datatable-row-left[data-index="'+i.data("index")+'"]'));var r=i.find('input[type="checkbox"]');if(r.length&&!r.is(":disabled")){n===e&&(n=!r.is(":checked")),a.isDataTable?s.find('.datatable-row[data-index="'+i.data("index")+'"]').toggleClass("checked",n):i.toggleClass("checked",n);var l=i.data("id");this.checkItems[l]=n,r.prop("checked",n).trigger("change"),o||(i.hasClass("table-parent")&&s.find((a.isDataTable?".fixed-left ":"")+"tbody>tr.parent-"+l).each(function(){a.checkRow(t(this),n,!0)}),a.updateCheckUI())}},r.prototype.updateCheckUI=function(){var e=this,i=e.getTable(),n=i.find(e.isDataTable?".fixed-left tbody>tr":"tbody>tr").not(".group-summary"),o=!1,a=null,s=0,r=!1,l=n.length;n.each(function(n){var c=t(this),h=c.find('input[type="checkbox"]');if(!h.length)return void l--;r=h.is(":checked");var d=e.isDataTable?i.find('.datatable-row[data-index="'+c.data("index")+'"]'):c;d.toggleClass("checked",r),d.toggleClass("row-check-begin",r&&!o),a&&a.toggleClass("row-check-end",!r&&o),r&&(s+=1),a=d,o=r,l===n+1&&d.toggleClass("row-check-end",r)}),e.$.toggleClass("has-row-checked",s>0).find(".check-all").toggleClass("checked",!(!l||s!==l)),e.updateStatistic(),e.options.onCheckChange&&e.options.onCheckChange(),i.trigger("checkChange")},r.DEFAULTS={checkable:!0,checkOnClickRow:!0,ajaxForm:!1,selectable:!0,fixHeader:!a,fixFooter:!a,iframeWidth:900,replaceId:"self",nestLevelIndent:18,nested:!1,preserveNested:!0,hot:!1,iframeModalTrigger:".iframe:not(.disabled,[disabled])"},t.fn.table=function(e){return this.each(function(){var n=t(this),o=n.data(i),a="object"==typeof e&&e;o||n.data(i,o=new r(this,a)),"string"==typeof e&&o[e]()})},r.NAME=i,t.fn.table.Constructor=r,t(function(){t('[data-ride="table"]').table()})}(jQuery,void 0),function(t,e,i){t.fn._ajaxForm=t.fn.ajaxForm;var n={timeout:e.config?e.config.timeout:0,dataType:"json",method:"post"},o="";t.fn.enableForm=function(e,n,o){return e===i&&(e=!0),this.each(function(){var i=t(this);n||i.find('[type="submit"]').attr("disabled",e?null:"disabled"),!o&&i.hasClass("load-indicator")&&i.toggleClass("loading",!e),i.toggleClass("form-disabled",!e)})},t.enableForm=function(e,i,n,o){"string"==typeof e||e instanceof t?e=t(e):(o=n,n=i,i=e,e=t("form")),e.enableForm(i!==!1,n,o)},t.disableForm=function(e,i,n){t.enableForm(e,!1,i,n)};var a=function(e,i,n){"string"==typeof i&&(n=i,i=null),n=n||"show",t.zui.messager?t.zui.messager[n](e,i):alert(e)};t.ajaxForm=function(s,r){var l=t(s);if(l.length>1)return l.each(function(){t.ajaxForm(this,r)});"function"==typeof r&&(r={complete:r}),r=t.extend({},n,l.data(),r);var c=r.beforeSubmit,h=r.error,d=r.success,u=r.finish;delete r.finish,delete r.success,delete r.onError,delete r.beforeSubmit,r=t.extend({beforeSubmit:function(n,a,s){if((c&&c(n,a,s))===!1)return!1;l.removeClass("form-watched").enableForm(!1);var r={},h=a.find('[type="file"]');r.fileapi=h.length&&h[0].files!==i,r.formdata=e.FormData!==i;var d=r.fileapi&&a.find('input[type="file"]:enabled').filter(function(){return""!==t(this).val()}),u=d.length,p="multipart/form-data",f=a.attr("enctype")==p||a.attr("encoding")==p,g=r.fileapi&&r.formdata,m=u&&!g||f&&!r.formdata; +m&&(""==o&&(o=s.url),s.url!=o&&(s.url=o),s.url=s.url.indexOf("&")>=0?s.url+"&HTTP_X_REQUESTED_WITH=XMLHttpRequest":s.url+"?HTTP_X_REQUESTED_WITH=XMLHttpRequest")},success:function(i,n,o){if((d&&d(i,n,o,l))!==!1){try{"string"==typeof i&&(i=JSON.parse(i))}catch(s){}if(null===i||"object"!=typeof i)return i?alert(i):a("No response.","danger");var c=r.responser?t(r.responser):l.find(".form-responser");c.length||(c=t("#responser"));var h=i.message,p=function(){var n=i.callback;if(n)if("object"==typeof n){var o=n.target?e[n.target]:e,a=o[n.name];a.apply(l,Array.isArray(n.params)?n.params:[n.params])}else{var s=n.indexOf("("),r=(s>0?n.substr(0,s):n).split("."),c=e,h=r[0];r.length>1&&(h=r[1],"top"===r[0]?c=e.top:"parent"===r[0]&&(c=e.parent));var a=c[h];if("function"==typeof a){var d=[];return s>0&&")"==n[n.length-1]&&(d=t.parseJSON("["+n.substring(s+1,n.length-1)+"]")),d.push(i),a.apply(l,d)}}};if("success"===i.result){var f=r.locate||i.locate,g=r.closeModal||i.closeModal,m=r.ajaxReload||i.ajaxReload;if(l.enableForm(!0,!!(f||g||m)),h){var v=l.find('[type="submit"]').first(),y=!1;v.length&&(v.popover({container:"body",trigger:"manual",content:h,tipClass:"popover-in-modal popover-success popover-form-result",placement:i.placement||v.data("placement")||r.popoverPlacement||"right"}).popover("show"),setTimeout(function(){v.popover("destroy")},r.popoverTime||2e3),y=!0),c.length&&(c.html(''+h+"").show().delay(3e3).fadeOut(100),y=!0),y||a(h,"success")}if(u)return u(i,!0,l);if(g&&setTimeout(t.zui.closeModal,"number"==typeof g?g:r.closeModalTime||2e3),p()===!1)return;if(f)if("loadInModal"==f){var b=t(".modal");setTimeout(function(){b.load(b.attr("ref"),function(){t(this).find(".modal-dialog").css("width",t(this).data("width")),t.zui.ajustModalPosition()})},1e3)}else"parent"===f||"top"===f?e[f]&&setTimeout(function(){e[f].location.reload()},1200):"reload"===f?setTimeout(function(){e.location.href=e.location.href},1200):setTimeout(function(){t.apps?t.apps.open(f):e.location.href=f},1200);if(m){var w=t(m);w.length&&w.load(e.location.href+" "+m,function(){w.find('[data-toggle="modal"]').modalTrigger()})}}else{if(l.enableForm(),"string"==typeof h)c.length?c.html(''+h+"").show().delay(3e3).fadeOut(100):a(h,"danger");else if("object"==typeof h){var x=!1,C=[];t.each(h,function(e,i){var n=t.isArray(i)?i.join(""):i,o=t("#"+e);if(!o.length)return void C.push(n);var a=e+"Label",s=t("#"+a);if(!s.length){var r=o.closest(".input-group").length,l=o.closest("td").length;s=t('
    ').appendTo(l?o.closest("td"):r?o.closest(".input-group").parent():o.parent())}s.empty().append(n),o.addClass("has-error");var c=function(){var e=t("#"+a);if(e.length)return e.remove(),o.removeClass("has-error"),!0};o.on("change input mousedown",c);var h=t("#"+e+"_chosen");if(h.length&&h.find(".chosen-single,.chosen-choices").addClass("has-error").on("mousedown",function(){c()===!0&&t(this).removeClass("has-error")}),!x){var d=o[0];if(o.hasClass("chosen"))o.trigger("chosen:activate").trigger("chosen:open"),d=o.parent().find(".chosen-container")[0];else if(o.is("textarea")&&o.data("keditor")){var u=o.data("keditor");u.focus(),u.edit.doc.body.focus(),d=o.parent().find(".ke-container")[0]}else o.focus();d.scrollIntoView&&d.scrollIntoView(),x=!0}}),C.length&&a(C.join(";"),"danger")}if(u)return u(i,!1,l);if(p()===!1)return}}},error:function(t,i,n){if((h&&h(t,i,n,l))!==!1){l.enableForm();var o="timeout"==i||"error"==i?e.lang?e.lang.timeout:i:t.responseText+i+n;a(o,"danger")}}},r),l._ajaxForm(r).data("zui.ajaxform",!0),l.on("click","[data-form-action]",function(){l.attr("action",t(this).data("formAction")).submit()})},t.setAjaxForm=function(e,i,n){t.ajaxForm(e,t.isPlainObject(i)?i:{finish:i,beforeSubmit:n})},t.fn.ajaxForm=function(e){return this.each(function(){t.ajaxForm(this,e)})},t.fn.setInputRequired=function(){return this.each(function(){var e=t(this),i=e.parent();i.is(".input-control,td")?i.addClass("required"):e.is(".chosen")?e.attr("required",null).next(".chosen-container").addClass("required"):i.addClass("required"),e.attr("required",null);var n=i.closest(".input-group");n.length&&1===n.find(".required,input[required],select[required]").length&&n.addClass("required")})},t(function(){t('.form-ajax,form[data-type="ajax"]').ajaxForm(),setTimeout(function(){var i=e.config.requiredFields,n=t("form");i&&(i=i.split(",")),i&&i.length&&t.each(i,function(t,e){n.find("#"+e).attr("required","required")}),n.find("input[required],select[required],textarea[required]").setInputRequired()},400),t('form[target="hiddenwin"]').on("submit",function(){var e=t(this);e.data("zui.ajaxform")||e.enableForm(!1).data("disabledTime",(new Date).getTime())}).on("click",function(){var e=t(this),i=e.data("disabledTime");i&&(new Date).getTime()-i>1e4&&e.enableForm(!0).data("disabledTime",null)})})}(jQuery,window,void 0),function(t){"use strict";var e="zui.searchList",i=function(t,e){if(t&&t.length)for(var i=0;i
    ').append(s)),i.$menu.append(s),i.$menu.removeClass("loading"),i.isLoaded=!0,e&&e(!0)},error:function(){i.$menu.removeClass("loading").append('
    '+(n.errorText||window.lang&&window.lang.timeout)+"
    "),e&&e(!1)}},n.ajax))},n.prototype.scrollTo=function(t){t.length&&t[0].scrollIntoViewIfNeeded&&t[0].scrollIntoViewIfNeeded({behavior:"smooth"})},n.prototype.getItems=function(){return this.$.find(this.options.selector).addClass("search-list-item")},n.prototype.getActiveItem=function(){return this.getItems().filter(".active:first")},n.prototype.search=function(e){var n=this,o=void 0===e||null===e||""===e;n.$.toggleClass("has-search-text",!o);var a=n.getItems().removeClass("active");if(o)a.removeClass("hidden");else{var s=e.trim().split(" ");a.each(function(){var e=t(this),n=(e.text()+" "+(e.data("key")||e.data("filter")||"")).trim();e.toggleClass("hidden",!i(s,n))})}n.scrollTo(a.not(".hidden").first().addClass("active")),n.$.trigger("onSearchComplete",e)},n.DEFAULTS={selector:".list-group a:not(.not-list-item)",searchBox:".search-box",onSelectItem:null},t.fn.searchList=function(i){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof i&&i;a||o.data(e,a=new n(this,s)),"string"==typeof i&&a[i]()})},n.NAME=e,t.fn.searchList.Constructor=n,t(function(){t('[data-ride="searchList"]').searchList()})}(jQuery),function(t){"use strict";var e="zui.labelSelector",i=function(n,o){var a=this;a.name=e,a.$=t(n),o=a.options=t.extend({},i.DEFAULTS,this.$.data(),o),a.$.hide(),a.update()};i.prototype.select=function(t){t+="",this.$wrapper.find(".label.active").removeClass("active"),this.$wrapper.find('.label[data-value="'+t+'"]').addClass("active"),this.$.val(t).trigger("change")},i.prototype.update=function(){var e=this,i=e.options,n=e.$wrapper;if(!n){if(i.wrapper)n=t(i.wrapper);else{var o=e.$.next();n=o.hasClass(".label-selector")?o:t('
    ')}n.parent().length||e.$.after(n),e.$wrapper=n,n.on("click",".label",function(i){var n=e.$.val(),o=t(this).data("value");e.hasEmptyValue!==!1&&o==n&&(o=e.hasEmptyValue),e.select(o),i.preventDefault()})}n.empty();var a=e.$.val();e.hasEmptyValue=!1,e.$.children("option").each(function(){var e=t(this),o={label:e.text(),value:e.val()},s=(""===o.value||"0"===o.value)&&!o.label,r=t(i.labelTemplate||'');i.labelClass&&!s&&r.addClass(i.labelClass),i.labelCreator?r=i.labelCreator(r):(r.data("option",o).attr("data-value",o.value),s?r.addClass("empty").append(''):r.text(o.label).toggleClass("active",a===o.value)),n.append(r)})},i.DEFAULTS={},t.fn.labelSelector=function(n){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof n&&n;a||o.data(e,a=new i(this,s)),"string"==typeof n&&a[n]()})},i.NAME=e,t.fn.labelSelector.Constructor=i,t(function(){t('[data-provide="labelSelector"]').labelSelector()})}(jQuery),function(t){"use strict";var e="zui.fileInput",i=t.BYTE_UNITS={B:1,KB:1024,MB:1048576,GB:1073741824,TB:1099511627776},n=t.formatBytes=function(t,e,n){return void 0===e&&(e=2),n||(n=ts.fileMaxSize&&(c.val(""),(window.bootbox||window).alert(s.fileSizeError.format(n(s.fileMaxSize)))),r.update()}),r.update()};a.prototype.getFile=function(){var t=this.$input.prop("files");return t&&t[0]},a.prototype.update=function(){var t=this,e=t.$,i=t.getFile(),o=!i;e.toggleClass("normal",!o).toggleClass("empty",o),i?(t.oldName=i.name,e.find(".file-title").text(i.name).attr("title",i.name),e.find(".file-size").text(n(i.size)),e.find(".file-editbox").val(i.name).attr("size",i.name.length),t.options.onSelect&&t.options.onSelect(i,t)):e.find(".file-editbox").val("")},a.DEFAULTS={fileMaxSize:0,fileSizeError:"无法上传大于 {0} 的文件。"},t.fn.fileInput=function(i){return this.each(function(){var n=t(this),o=n.data(e),s="object"==typeof i&&i;o||n.data(e,o=new a(this,s)),"string"==typeof i&&o[i]()})},a.NAME=e,t.fn.fileInput.Constructor=a,t(function(){t('[data-provide="fileInput"]').fileInput()});var s="zui.fileInputList",r=function(e,i){var n=this;n.name=s;var o=n.$=t(e);i=n.options=t.extend({},r.DEFAULTS,this.$.data(),i),n.$template=o.find(".file-input").detach(),n.add()};r.prototype.add=function(){var t=this,e=t.options,i=t.$template.clone();"before"===e.appendWay?t.$.prepend(i):t.$.append(i),i.fileInput({fileMaxSize:e.eachFileMaxSize,fileSizeError:e.fileSizeError,onDelete:function(e){e.$.remove(),t.options.onDelete&&t.options.onDelete(e,t)},onSelect:function(e,i){t.add(),t.options.onSelect&&t.options.onSelect(e,i,t)}})},r.DEFAULTS={fileMaxSize:0,eachFileMaxSize:0,appendWay:"after",fileSizeError:"无法上传大于 {0} 的文件。"},t.fn.fileInputList=function(e){return this.each(function(){var i=t(this),n=i.data(s),o="object"==typeof e&&e;n||i.data(s,n=new r(this,o)),"string"==typeof e&&n[e]()})},r.NAME=s,t.fn.fileInputList.Constructor=r,t(function(){t('[data-provide="fileInputList"]').fileInputList()})}(jQuery),function(t){window.config||(window.config={}),t.createLink=window.createLink=function(e,n,o,a,s,r,l){if("object"==typeof e)return t.createLink(e.moduleName,e.methodName,e.vars,e.viewType,e.isOnlyBody,e.hash,e.tid);if(t.tabSession&&!l&&(l=t.tabSession.getTid()),a||(a=config.defaultView),s||(s=!1),o)for("string"==typeof o&&(o=o.split("&")),i=0;i'+d+"")}}t.val()||(time=e(a.format("hh:mm")),time=time-time%10+10,t.val(n(time)))};t.fn.timeSpanControl=function(i){return this.each(function(){var s=t(this),r=t.extend({},i,s.data()),l=s.find('[name="begin"],.control-time-begin'),c=s.find('[name="end"],.control-time-end'),h=function(){var t=l.val();if(s.find(".hide-empty-begin").toggleClass("hide",!t),t){var i=n(e(t)+30);c.find('option[value="'+i+'"]').length&&c.val(i),r.onChange&&r.onChange(c,i)}};if(s.data("timeSpanControlInit")){if(r.begin){var d=o(r.begin).format("hh:mm");l.find('option[value="'+d+'"]').length&&l.val(d),r.onChange&&r.onChange(l,d)}if(r.end){var u=o(r.end).format("hh:mm");c.find('option[value="'+u+'"]').length&&c.val(u),r.onChange&&r.onChange(c,u)}}else l.on("change",h),a(l,r.begin),a(c,r.end),s.data("timeSpanControlInit",!0);r.end||h()})},t.timeSpanControl={convertTimeToNum:e,convertNumToTime:n,initTimeSelect:a,createTime:o};var s=t.setSearchType=function(e,i){var n=t("#searchType");e||(e=n.val()),e=e||"bug",n.val(e);var o=t("#searchTypeMenu");o.find("li.selected").removeClass("selected");var a=o.find('a[data-value="'+e+'"]'),s=a.text();a.parent().addClass("selected"),t("#searchTypeName").text(s),i||t("#searchInput").focus()};t.gotoObject=function(e,i){if(e||(e=t("#searchType").val()),i||(i=t("#searchInput").val()),i&&e)if(i=i.replace(/[^\d]/g,"")){var n=e.split("-");e=n[0];var o=n.length>1?n[1]:"testsuite"===e?"library":"view",a=t.createLink(e,o,"id="+i);t.apps?t.apps.open(a):window.location.href=a}else{var s={zh_cn:"请输入数字ID进行搜索",zh_tw:"請輸入數值ID行搜索"};alert(lang.searchTip||s[t.zui.clientLang()]||"Please enter a numberic id to search")}t("#searchInput").val(i).focus()},t(function(){s(null,!0),t(document).on("keydown",function(e){e.ctrlKey&&71===e.keyCode&&(t("#searchInput").val("").focus(),e.stopPropagation(),e.preventDefault())})}),t.removeAnchor=window.removeAnchor=function(t){var e=t.lastIndexOf("#");return e>-1?t.substr(0,e):t},t.refreshPage=function(t){t?window.top.location.reload():window.location.reload()},t.selectLang=window.selectLang=function(e){t.cookie("lang",e,{expires:config.cookieLife,path:config.webRoot}),t.ajaxSendScore("selectLang"),t.refreshPage(1)},t.selectTheme=window.selectTheme=function(e){t.cookie("theme",e,{expires:config.cookieLife,path:config.webRoot}),t.ajaxSendScore("selectTheme"),t.refreshPage(1)},t.zui.Picker&&(t.extend(t.zui.Picker.DEFAULTS,{optionRender:function(e,i,n){if("user"===n.options.type){var o=n.options.users;if(!o)return;var a=o[i.value];if(!a)return;if(e.find(".picker-option-text").text(a.realname||a.account),e.hasClass("picker-user-option"))return;return e.prepend(t('
    ').avatar({user:a})),a.deptName&&e.append(t('').text(a.deptName)),a.roleName&&e.append(t('').text(a.roleName)),e.addClass("picker-user-option")}},checkable:!0,maxListCount:500,disableScrollOnShow:!1}),t.zui.setUserPickerInfos=function(e){t.zui.Picker.DEFAULTS.users=t.extend({},t.zui.Picker.DEFAULTS.users,e)},t(function(){t(".picker-select[data-pickertype!='remote']").picker({chosenMode:!0}),t("[data-pickertype='remote']").each(function(){var e=t(this).attr("data-pickerremote");t(this).picker({chosenMode:!0,remote:e})}),window.pickerUsers&&t.zui.setUserPickerInfos(window.pickerUsers),t(".user-picker").picker({type:"user"})})),t.chosenDefaultOptions={middle_highlight:!0,disable_search_threshold:1,compact_search:!0,allow_single_deselect:!0,placeholder_text_single:" ",placeholder_text_multiple:" ",search_contains:!0,max_drop_width:500,max_drop_height:245,no_wrap:!0,drop_direction:function(){var e=t(this.container).closest(".table-responsive:not(.scroll-none)");if(e.length){if(this.drop_directionFixed)return this.drop_directionFixed;e.css("position","relative");var i="down",n=this.container.find(".chosen-drop"),o=this.container.position(),a=n.outerHeight();return o.top>=a&&o.top+31+a>e.outerHeight()&&(i="up"),this.drop_directionFixed=i,i}return"auto"}},t.chosenSimpleOptions=t.extend({},t.chosenDefaultOptions,{disable_search_threshold:6}),t.fn._chosen=t.fn.chosen,t.fn.chosen=function(e){return"string"==typeof e?this._chosen(e):this.each(function(){var i=t(this).addClass("chosen-controled");return i._chosen(t.extend({},i.hasClass("chosen-simple")?t.chosenSimpleOptions:t.chosenDefaultOptions,i.data(),e))})},t.fn.chosen.Constructor=t.fn._chosen.Constructor,t(function(){t(".chosen,.chosen-simple").each(function(){var e=t(this);e.closest(".template").length||e.chosen()})}),t.extend(t.fn.pager.Constructor.DEFAULTS,{maxNavCount:8,prevIcon:"icon-angle-left",nextIcon:"icon-angle-right",firstIcon:"icon-first-page",lastIcon:"icon-last-page",navEllipsisItem:"…",menuDirection:"dropup",pageSizeOptions:[5,10,15,20,25,30,35,40,45,50,100,200,500,1e3,2e3],elements:["total_text","size_menu","first_icon","prev_icon",'
    {page}/{totalPage}
    ',"next_icon","last_icon"],onPageChange:function(e,i){e.recPerPage!==i.recPerPage&&t.cookie(this.options.pageCookie,e.recPerPage,{expires:config.cookieLife,path:config.webRoot}),e.recPerPage!==i.recPerPage&&(window.location.href=this.createLink())}}),t.extend(!0,t.zui.Messager.DEFAULTS,{cssClass:"messagger-zt",icons:{success:"check-circle",info:"chat-line",warning:"exclamation-sign",danger:"exclamation-sign"}}),t.fn.reverseOrder=function(){return this.each(function(){var e=t(this);e.prependTo(e.parent())})};var r=function(e,i){var n=t(e);if(!n.data("historiesInited")){n.data("historiesInited",1),i=t.extend({},n.data(),i);var o=n.find(".histories-list"),a=!0,s=!1;n.on("click",".btn-reverse",function(){o.children("li").reverseOrder(),a=!a,t(this).find(".icon").toggleClass("icon-arrow-up",a).toggleClass("icon-arrow-down",!a);var e="#lastComment",i=t(e);i.length&&window.KindEditor&&(window.KindEditor.remove(e),i.kindeditor())}).on("click",".btn-expand-all",function(){var e=t(this).find(".icon");s=!s,e.toggleClass("icon-plus",!s).toggleClass("icon-minus",s),o.children("li").toggleClass("show-changes",s)}).on("click",".btn-expand",function(){t(this).closest("li").toggleClass("show-changes")}).on("click",".btn-strip",function(){var e=t(this),n=e.find(".icon"),o=n.hasClass("icon-code");n.toggleClass("icon-code",!o).toggleClass("icon-text",o),e.attr("title",o?i.original:i.textdiff),e.closest("li").toggleClass("show-original",o)}),o.find(".btn-strip").attr("title",i.original);var r=n.find(".modal-comment").modal({show:!1}).on("shown.zui.modal",function(){var t=r.find("#comment");t.length&&(t.focus(),window.editor&&window.editor.comment&&window.editor.comment.focus())}).on("show.zui.modal",function(){var e=r.find("#comment");e.length&&!e.data("keditor")&&t.fn.kindeditor&&e.kindeditor()});n.on("click",".btn-comment",function(t){r.modal("toggle"),t.preventDefault()}).on("click",".btn-edit-comment,.btn-hide-form",function(){t(this).closest("li").toggleClass("show-form")});var l=n.find(".comment-edit-form");l.ajaxForm({success:function(t,e,i,n){setTimeout(function(){l.closest("li").removeClass("show-form")},2e3)}})}};t.fn.histories=function(t){return this.each(function(){r(this,t)})},t(function(){t(".histories").histories()});var l=0,c=0;t.toggleSidebar=function(e){var i=t("#sidebar");if(i.length){var n=t("main");if(void 0===e)e=n.hasClass("hide-sidebar");else if(e&&!n.hasClass("hide-sidebar"))return;n.toggleClass("hide-sidebar",!e),clearTimeout(l),t.zui.store.set(c,e);var o=i.children(".cell"),a={overflow:"visible",maxHeight:"initial"};e?(i.addClass("showing"),l=setTimeout(function(){i.removeClass("showing"),i.trigger("sidebar.toggle",e)},210)):(i.trigger("sidebar.toggle",e),t(window).width()<1900&&(a={overflow:"hidden",maxHeight:t(window).height()-45})),o.css(a)}};var h=t.initSidebar=function(){var e=t("#sidebar");if(e.length){if(e.data("init"))return!0;c="sidebar:"+(e.data("id")||config.currentModule+"/"+config.currentMethod);var i=t("main");if(i.length){i.on("click",".sidebar-toggle",function(){t.toggleSidebar(i.hasClass("hide-sidebar"))});var n=t.zui.store.get(c,e.data("hide")!==!1);n===!1&&e.addClass("no-animate"),t.toggleSidebar(n),n===!1&&setTimeout(function(){e.removeClass("no-animate")},500);var o=e.find(".sidebar-toggle");if(o.length){var a=function(){var e=o[0].getBoundingClientRect(),i=t(window).height(),n=Math.max(0,Math.floor(Math.min(i-40,e.top+e.height)-Math.max(e.top,0))/2)+(e.top<0?0-e.top:0);o.removeClass("fade").find(".icon").css("top",n+(t.zui.browser.isIE()?(i-80)/2:0))};a(),e.data("init",1).on("sidebar.toggle",a);var s=t.zui.browser.isIE()?1500:0,r=0,l=null,h=function(){var t=Date.now();return l&&(clearTimeout(l),l=null),t-rtr input[type="checkbox"]:checked');i.each(function(){var i=parseInt(t(this).val(),10);NaN!==i&&e.push(i)}),t.cookie("checkedItem",e.join(","),{expires:config.cookieLife,path:config.webRoot})},t.extend(t.fn.modal.bs.Constructor.DEFAULTS,{scrollInside:!0,backdrop:"static",headerHeight:100}),t.extend(t.zui.ModalTrigger.DEFAULTS,{scrollInside:!0,backdrop:"static"}),t.fn.initIframeModal=function(){return this.each(function(){var e=t(this);if(!e.is("[disabled],.disabled")&&!e.parents('[data-ride="table"],.skip-iframe-modal').length){var i={type:"iframe"};e.hasClass("export")&&t.extend(i,{width:800,shown:setCheckedCookie},e.data()),e.modalTrigger(i)}})},t(function(){t("a.iframe,.export").initIframeModal()}),t.fixedTableHead=window.fixedTableHead=function(e,i){var n=t(e);if(n.is("table")||(n=n.find("table")),n.length){var o=t(i||window),a=null,s=function(){var e=n.children("thead"),i=e[0].getBoundingClientRect(),o=n.next(".fixed-head-table");if(i.top<0){var s=e.width();if(o.length){if(a!==s){a=s;var r=o.find("th");e.find("th").each(function(e){r.eq(e).width(t(this).width())})}}else{var o=t("
    ").addClass(n.attr("class")),l=e.clone(),r=l.find("th");e.find("th").each(function(e){r.eq(e).width(t(this).width())}),o.append(l).insertAfter(n)}o.css({left:i.left,width:i.width}).show()}else o.hide()};o.on("scroll",s).on("resize",s),s()}},t(document).on("click","tr[data-url]",function(){var e=t(this),i=e.data("href")||e.data("url");i&&(window.location.href=i)}),"yes"===config.onlybody&&self===parent&&(window.location.href=window.location.href.replace("?onlybody=yes","").replace("&onlybody=yes","")),t(function(){t("body").addClass("m-{currentModule}-{currentMethod}".format(config))});var d,u,p,f,g,m=function(){d||(d=t("#subNavbar"),u=t("#pageNav"),p=t("#pageActions"),f=d.children(".nav"),g=f.outerWidth());var e=d.outerWidth(),i=u.outerWidth()||0,n=p.outerWidth()||0;if(i=i?i+15:0,n=n?n+15:0,!i&&!n)return void f.css({maxWidth:null,left:null,position:"static"});var o=Math.max(300,e-i-n),a=Math.min(o,g),s=(e-a)/2,r=i&&s.btn-toolbar");if(e.length){var i,n,o=e.children(),a=o.length,s=!1,r=null;if(a)for(o.each(function(e){i=t(this),n=i.is(".divider"),n&&!r&&i.hide(),s||n||(s=!0),r=n?null:i,!n||e!==a-1&&0!==e||i.hide()});i.length&&i.is(".divider");)i=i.hide().prev();s||e.hide()}};t(function(){t(".input-group,.btn-group").fixInputGroup(),x()}),window.holders&&t.each(window.holders,function(e){var i=t("#"+e);i.length&&i.is("input")&&i.attr("placeholder",window.holders[e])}),t(function(){var e=t(".table-responsive"),i=t.fixTableResponsive=function(){e.each(function(){this.scrollHeight-3<=this.clientHeight&&this.scrollWidth-3<=this.clientWidth?t(this).addClass("scroll-none").css("overflow","visible"):t(this).removeClass("scroll-none").css("overflow","auto")})};e.length&&(t(window).on("resize",i),setTimeout(i,100))});var C=function(){var e=this,i=t(e),n=i.closest("tr").find("textarea");if(n.length){var o=32;n.each(function(){var e=t(this).closest("td"),i=e.css("height");e.css("height",this.style.height),this.style.height="auto";var n=this.value?this.scrollHeight+2:32;o=Math.max(o,n),e.css("height",i)}),n.css("height",o)}else{e.style.height="auto";var a=e.value?e.scrollHeight+2:32;e.style.height=a+"px"}};t.autoResizeTextarea=function(e){t(e).each(C)},t(function(){t("textarea.autosize").each(C),t(document).on("input paste change","textarea.autosize",C)}),t(function(){var e=t("#dropMenu,.drop-menu");e.length&&e.on("click",".toggle-right-col",function(e){t(this).closest("#dropMenu,.drop-menu").toggleClass("show-right-col"),e.stopPropagation(),e.preventDefault()})});var _="undefined"!=typeof InstallTrigger;t.zui.browser.firefox=_,t("html").toggleClass("is-firefox",_).toggleClass("not-firefox",!_),t(function(){var e=t("#mainContent>.main-col"),i=e.children(".main-actions");if(i.length){var n=i.prev();if(i.length&&n.length){t('
    ').css("height",i.outerHeight()).insertAfter(i);var o=0,a=function(){var e=n[0].getBoundingClientRect(),s=e.top+e.height+120>t(window).height();if(t("body").toggleClass("main-actions-fixed",s),s){var r=n.width();r?i.width(r):o<10&&setTimeout(a,1e3)}o++};t.resetToolbarPosition=a,a(),t(window).on("resize scroll",a)}}}),t(document).on("show.zui.modal",function(e){t("body.body-modal").length&&window.parent&&window.parent!==window&&t(e.target).is(".modal")&&window.parent.$("body").addClass("hide-modal-close")}).on("hidden.zui.modal",function(e){ +t("body.body-modal").length&&window.parent&&window.parent!==window&&window.parent.$("body").removeClass("hide-modal-close")}).on("loaded.zui.modal",function(e){t("body").removeClass("hide-modal-close")}),t(function(){var e=t(".dropdown-menu.with-search");e.length&&(e.find(".menu-search").on("click",function(t){return t.stopPropagation(),!1}),e.on("keyup change paste","input",function(){var e=t(this),i=e.closest(".dropdown-menu.with-search"),n=e.val().toLowerCase(),o=i.find(".option");""==n?o.removeClass("hide"):o.each(function(){var e=t(this);e.toggleClass("hide",e.text().toString().toLowerCase().indexOf(n)<0&&e.data("key").toString().toLowerCase().indexOf(n)<0)})}),e.parents(".dropdown-submenu").one("mouseenter",function(){var e=t(this).find(".dropdown-list")[0];e&&e.getBoundingClientRect&&setTimeout(function(){var i=270,n=e.getBoundingClientRect();n.top<0&&(i=Math.min(270,n.height)+n.top),e.style.maxHeight=Math.min(270,i,t(window).height()-28)+"px"},50)})),t(".dropdown-menu.with-search .menu-search").on("click",function(t){return t.stopPropagation(),!1})})}(jQuery),function(t){function e(){if(!config.skipRedirect&&!window.skipRedirect){var e=window.parent,i=config.currentModule,n=config.currentMethod;if("file"!==i||"download"!==n){var o="index"===i&&"index"===n,a="#_single"===location.hash||/(\?|\&)_single/.test(location.search)||o||!t("#mainHeader,#editorNav").length||"tutorial"===i||"install"===i||"upgrade"===i||"user"===i&&("login"===n||"deny"===n)||"my"===i&&"changepassword"===n||t("body").hasClass("allow-self-open"),s=location.href;if(e===window&&!a){var r=location.pathname+location.search+location.hash;return void(location.href=t.createLink("index","index","")+"#app="+encodeURIComponent(r))}if(e!==window&&e.$.apps){o&&e.location.reload();var l=window.name;if(0===l.indexOf("app-")){t.apps=window.apps=e.$.apps;var c=l.substring(4);t.appCode=c,t(document).on("click",function(t){var i=e.document.getElementById(window.name);if(i){var n=e.document.getElementById(i.name)||i;if(n){var o;"function"==typeof Event?o=new Event(t.type,{bubbles:!0}):(o=document.createEvent("Event"),o.initEvent(t.type,!0,!0)),n.dispatchEvent(o)}}}).on("click","a,.open-in-app,.show-in-app",function(e){var i=t(this);if(!i.is("[data-modal],[data-toggle],[data-ride],[data-tab],.iframe,.not-in-app,[target]")&&!i.data("zui.modaltrigger")){var n=i.hasClass("show-in-app")?"":i.attr("href")||(i.is("a")?"":i.data("url")),o=i.data("app")||i.data("group");if(n){if(0===n.indexOf("javascript:")||"#"===n[0])return;var a=t.parseLink(n);if(a.external||"file"===a.moduleName&&"download"===a.methodName)return;if("index"===a.moduleName&&"index"===a.methodName)return window.location.reload(),void e.preventDefault()}else if(!o)return;o||(o=t.apps.getAppCode(n)),o&&("help"===o&&(t.apps.appsMap.help.text=i.text(),t.apps.appsMap.help.url||(t.apps.appsMap.help.url=n)),t.apps.open(n,o)&&e.preventDefault())}}),t.apps.updateUrl(c,s,document.title)}}}}}function i(){var e=t("#navbar>.nav");if(e.length){var i=t("#heading"),n=+i.css("left").replace("px",""),o=i.outerWidth(),a=e.width(),s=t("#mainHeader>.container").width()-2*n,r=Math.floor((s-a)/2);e.css("marginLeft",r>>0;if(0===o)return!1;for(var a=0|e,s=Math.max(a>=0?a:o-Math.abs(a),0);s1&&("?"===e[0]&&(e=e.substr(1)),e.split("&").forEach(function(t){var e=t.split("=",2);if(e.length>1)try{i[e[0]]=decodeURIComponent(e[1])}catch(n){i[e[0]]=""}else i[e[0]]=""})),t?i[t]:i},t.parseLink=function(e){if(!e)return{};var i=0===e.indexOf("http:")||0===e.indexOf("https:");if(i){var n=window.location.origin;if(e.indexOf(n)<0)return{external:!0,url:e};e=e.substr((n+config.webRoot).length)}var o=e.split("#"),a=o[0].split("?"),s=a[1],r=s?t.getSearchParam("",s):{},l=a[0],c={url:e,isOnlyBody:"yes"===r.onlybody,vars:[],hash:o[1]||"",params:r,tid:r.tid||""};if("GET"===config.requestType){c.moduleName=r[config.moduleVar]||"index",c.methodName=r[config.methodVar]||"index",c.viewType=r[config.viewVar]||config.defaultView;for(var h in r)h!==config.moduleVar&&h!==config.methodVar&&h!==config.viewVar&&"onlybody"!==h&&"tid"!==h&&c.vars.push([h,r[h]])}else{var d=l.lastIndexOf("/");d===l.length-1&&(l=l.substr(0,d),d=l.lastIndexOf("/")),d>=0&&(l=l.substr(d+1));var u=l.lastIndexOf(".");u>=0?(c.viewType=l.substr(u+1),l=l.substr(0,u)):c.viewType=config.defaultView;var p=l.split(config.requestFix);if(c.moduleName=p[0]||"index",c.methodName=p[1]||"index",p.length>2)for(var f=2;f.nav>li").length>10&&(i(),t(window).on("resize",i)),setTimeout(n,1e3)})}(jQuery),function(t){"use strict";function e(e,i){"object"!=typeof i&&(i={user:i});var n=t(e);i=t.extend({},n.data(),i);var o=i.user;"string"==typeof o&&(o={account:o});var a={},s=i.size;s&&(a.width=s,a.height=s,a.lineHeight=s,Number.isNaN(+s)||n.addClass("size-"+s));var r=!!o.avatar;if(n.toggleClass("has-image",r).toggleClass("has-text",!r),n.empty(),r)n.append(t("").attr("src",o.avatar));else{var l=t.zui.strCode(o.account)*(i.hueDistance||43)%360;a.background="hsl("+l+","+(i.saturation||"40%")+","+(i.lightness||"60%")+")",Number.isNaN(+s)||(a.fontSize=Math.round(s/2)+"px");var c=o.name||o.realname||o.account;c=/^[\u4e00-\u9fa5\s]+$/.test(c)?c.length<=2?c:c.substring(c.length-2):/^[A-Za-z\d\s]+$/.test(c)?c[0].toUpperCase():c.length<=2?c:c.substring(0,2),n.append(t('').text(c))}return n.css(a)}t.fn.avatar=function(t){return this.each(function(){e(this,t)})}}(jQuery),$.zui.lang("de",{"zui.pager":{pageOfText:"Seite {0}",prev:"Zurück",next:"Nächste Seite",first:"Erste Seite",last:"Letzte Seite","goto":"Goto",pageOf:"Seite {page}",totalPage:"{totalPage} Seiten",totalCount:"Total: {recTotal} Artikel",pageSize:"{recPerPage} Artikel pro Seite",itemsRange:"Seiten {start} bis {end}",pageOfTotal:"Seite {page}/{totalPage}"},"zui.boards":{append2end:"Gehen Sie zum Ende"},"zui.browser":{tip:"Online. Sorgenfrei. Aktualisiere deinen Browser noch heute!"},"zui.calendar":{weekNames:["Son","Mon","Die","Mit","Don","Fri","Sam"],monthNames:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",year:"{0}Jahr",month:"{0}Monat",yearMonth:"{0}-{1}"},"zui.chosenIcons":{emptyIcon:"[Kein Icon]",commonIcons:"Gemeinsame Symbole",webIcons:"Web-Symbol",editorIcons:"Editor-Symbol",directionalIcons:"Pfeil Zusammenfluss",otherIcons:"Andere Symbole"},"zui.colorPicker":{errorTip:"Kein gültiger Farbwert"},"zui.datagrid":{errorCannotGetDataFromRemote:"Daten vom Remote-Server ({0}) können nicht abgerufen werden.",errorCannotHandleRemoteData:"Die vom Remote-Server zurückgegebenen Daten können nicht verarbeitet werden."},"zui.guideViewer":{prevStep:"Vorheriger Schritt",nextStep:"Nächster Schritt"},"zui.tabs":{reload:"Neu laden",close:"Schliessen",closeOthers:"Schließen Sie andere Registerkarten",closeRight:"Schließen Sie die rechte Registerkarte",reopenLast:"Letzten geschlossenen Tab wiederherstellen",errorCannotFetchFromRemote:"Inhalt kann nicht vom Remote-Server abgerufen werden ({0})."},"zui.uploader":{},datetimepicker:{days:["Sonntag","Montag","Diensteg","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["Son","Mon","Die","Mit","Don","Fri","Sam"],daysMin:["Son","Mon","Die","Mit","Don","Fri","Sam"],months:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",suffix:[],meridiem:[]},chosen:{no_results_text:"Nicht gefunden"},bootbox:{OK:"OK",CANCEL:"Stornieren",CONFIRM:"Bestätigen"}}),$.zui.lang("fr",{"zui.pager":{pageOfText:"Page {0}",prev:"Prev",next:"Suivant",first:"First",last:"Last","goto":"Goto",pageOf:"Page {page}",totalPage:"{totalPage} pages",totalCount:"Total: {recTotal} items",pageSize:"{recPerPage} per page",itemsRange:"De {start} à {end}",pageOfTotal:"Page {page} de {totalPage}"},"zui.boards":{append2end:"Aller jusqu'au bout"},"zui.browser":{tip:"Naviguez sans crainte sur Internet. Mettez votre navigateur à jour dès aujourd'hui!"},"zui.calendar":{weekNames:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],monthNames:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Août","Sep","Oct","Nov","Déc"],today:"Aujourd'hui",year:"{0} Année",month:"{0} Mois",yearMonth:"{0}-{1}"},"zui.chosenIcons":{emptyIcon:"[Aucune icône]",commonIcons:"Icônes communes",webIcons:"Icône Web",editorIcons:"Icône de l'éditeur",directionalIcons:"Flèche confluence",otherIcons:"Autres icônes"},"zui.colorPicker":{errorTip:"Pas une valeur de couleur valide"},"zui.datagrid":{errorCannotGetDataFromRemote:"Impossible d'obtenir les données du serveur distant ({0}).",errorCannotHandleRemoteData:"Impossible de traiter les données renvoyées par le serveur distant."},"zui.guideViewer":{prevStep:"Étape précédente",nextStep:"Prochaine étape"},"zui.tabs":{reload:"Recharger",close:"Fermer",closeOthers:"Fermez les autres onglets",closeRight:"Fermer l'onglet de droite",reopenLast:"Restaurer le dernier onglet fermé",errorCannotFetchFromRemote:"Impossible d'obtenir le contenu du serveur distant ({0})."},"zui.uploader":{},datetimepicker:{days:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],daysShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],daysMin:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],months:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Août","Sep","Oct","Nov","Déc"],monthsShort:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Août","Sep","Oct","Nov","Déc"],today:"Aujourd'hui",suffix:[],meridiem:[]},chosen:{no_results_text:"Pas trouvé"},bootbox:{OK:"D'accord",CANCEL:"Annuler",CONFIRM:"Confirmer"}}); diff --git a/www/theme/zui/css/min.css b/www/theme/zui/css/min.css index cdb728f284..d669612738 100644 --- a/www/theme/zui/css/min.css +++ b/www/theme/zui/css/min.css @@ -1,5 +1,5 @@ /*! - * ZUI: ZUI for Zentao - v1.10.0 - 2022-06-28 + * ZUI: ZUI for Zentao - v1.10.0 - 2022-06-30 * http://openzui.com * GitHub: https://github.com/easysoft/zui.git * Copyright (c) 2022 cnezsoft.com; Licensed MIT diff --git a/www/upgrade.php.tmp b/www/upgrade.php.tmp index cb16f99203..a2f2165848 100644 --- a/www/upgrade.php.tmp +++ b/www/upgrade.php.tmp @@ -65,6 +65,19 @@ $app->setDebug(); $config->installedVersion = $common->loadModel('setting')->getVersion(); if(($config->version[0] == $config->installedVersion[0] or (is_numeric($config->version[0]) and is_numeric($config->installedVersion[0]))) and version_compare($config->version, $config->installedVersion) <= 0) die(header('location: index.php')); +/* If run in container, upgrade automatically. */ +if($app->isContainer()) +{ + $upgradeModel = $common->loadModel('upgrade'); + $alterSQL = $upgradeModel->checkConsistency(); + if(!empty($alterSQL)) $upgradeModel->dao->query("SET @@sql_mode= '';" . $alterSQL); + + $config->set('default.method', 'execute'); + $app->session->set('upgrading', true); + $app->session->set('step', ''); + $app->post->set('fromVersion', str_replace( '.', '_', strtolower($config->installedVersion))); +} + /* Run it. */ $app->parseRequest(); if($common->checkUpgradeStatus()) $app->loadModule(); diff --git a/xuanxuan/XUANVERSION b/xuanxuan/XUANVERSION index 7aefc82460..9773998bc1 100644 --- a/xuanxuan/XUANVERSION +++ b/xuanxuan/XUANVERSION @@ -1 +1 @@ -v5.6.0 +v6.0.0 diff --git a/xuanxuan/XVERSION b/xuanxuan/XVERSION index 2df33d7697..e0ea36feef 100644 --- a/xuanxuan/XVERSION +++ b/xuanxuan/XVERSION @@ -1 +1 @@ -5.6 +6.0 diff --git a/xuanxuan/extension/xuan/misc/ext/control/ajaxgetclientpackage.php b/xuanxuan/extension/xuan/misc/ext/control/ajaxgetclientpackage.php index 54a96849c8..415dc210dd 100644 --- a/xuanxuan/extension/xuan/misc/ext/control/ajaxgetclientpackage.php +++ b/xuanxuan/extension/xuan/misc/ext/control/ajaxgetclientpackage.php @@ -10,6 +10,8 @@ class myMisc extends misc */ public function ajaxGetClientPackage($os = '') { + ini_set('memory_limit', '256M'); // Temporarily handle the problem that the ZenTao client file is too large. + set_time_limit (0); session_write_close(); diff --git a/xuanxuan/extension/xuan/misc/ext/control/downloadclient.php b/xuanxuan/extension/xuan/misc/ext/control/downloadclient.php index 565e15b164..d7549292d9 100644 --- a/xuanxuan/extension/xuan/misc/ext/control/downloadclient.php +++ b/xuanxuan/extension/xuan/misc/ext/control/downloadclient.php @@ -11,6 +11,8 @@ class myMisc extends misc */ public function downloadClient($action = 'check', $os = '') { + ini_set('memory_limit', '256M'); // Temporarily handle the problem that the ZenTao client file is too large. + if($_POST) { $os = $this->post->os;