From b1d3f7733cc546c42ca2bb539d980c063741a375 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 16 Nov 2023 08:43:59 +0800 Subject: [PATCH 001/235] * Adjust zahost search params. --- module/zahost/lang/de.php | 2 +- module/zahost/lang/en.php | 2 +- module/zahost/lang/fr.php | 2 +- module/zahost/lang/zh-cn.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/zahost/lang/de.php b/module/zahost/lang/de.php index c20cbcb3b4..0a362fbb7f 100644 --- a/module/zahost/lang/de.php +++ b/module/zahost/lang/de.php @@ -105,7 +105,7 @@ $lang->zahost->image->cancelDownloadSuccess = 'Successed to cancel image task'; $lang->zahost->empty = 'No Host'; $lang->zahost->statusList['wait'] = 'Wait'; -$lang->zahost->statusList['ready'] = 'Online'; +$lang->zahost->statusList['ready'] = 'Ready'; $lang->zahost->statusList['online'] = 'Online'; $lang->zahost->statusList['offline'] = 'Offline'; $lang->zahost->statusList['busy'] = 'Busy'; diff --git a/module/zahost/lang/en.php b/module/zahost/lang/en.php index c20cbcb3b4..0a362fbb7f 100644 --- a/module/zahost/lang/en.php +++ b/module/zahost/lang/en.php @@ -105,7 +105,7 @@ $lang->zahost->image->cancelDownloadSuccess = 'Successed to cancel image task'; $lang->zahost->empty = 'No Host'; $lang->zahost->statusList['wait'] = 'Wait'; -$lang->zahost->statusList['ready'] = 'Online'; +$lang->zahost->statusList['ready'] = 'Ready'; $lang->zahost->statusList['online'] = 'Online'; $lang->zahost->statusList['offline'] = 'Offline'; $lang->zahost->statusList['busy'] = 'Busy'; diff --git a/module/zahost/lang/fr.php b/module/zahost/lang/fr.php index c20cbcb3b4..0a362fbb7f 100644 --- a/module/zahost/lang/fr.php +++ b/module/zahost/lang/fr.php @@ -105,7 +105,7 @@ $lang->zahost->image->cancelDownloadSuccess = 'Successed to cancel image task'; $lang->zahost->empty = 'No Host'; $lang->zahost->statusList['wait'] = 'Wait'; -$lang->zahost->statusList['ready'] = 'Online'; +$lang->zahost->statusList['ready'] = 'Ready'; $lang->zahost->statusList['online'] = 'Online'; $lang->zahost->statusList['offline'] = 'Offline'; $lang->zahost->statusList['busy'] = 'Busy'; diff --git a/module/zahost/lang/zh-cn.php b/module/zahost/lang/zh-cn.php index 746a55c035..a81575d88b 100644 --- a/module/zahost/lang/zh-cn.php +++ b/module/zahost/lang/zh-cn.php @@ -105,7 +105,7 @@ $lang->zahost->image->cancelDownloadSuccess = '取消下载镜像任务成功'; $lang->zahost->empty = '暂时没有宿主机'; $lang->zahost->statusList['wait'] = '待初始化'; -$lang->zahost->statusList['ready'] = '在线'; +$lang->zahost->statusList['ready'] = '就绪'; $lang->zahost->statusList['online'] = '在线'; $lang->zahost->statusList['offline'] = '离线'; $lang->zahost->statusList['busy'] = '繁忙'; From 366c78fbb09b14b477e5c2cf35c7f43a3699a27d Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 16 Nov 2023 09:01:12 +0800 Subject: [PATCH 002/235] * Replace zanode search query. --- module/zanode/model.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/module/zanode/model.php b/module/zanode/model.php index bb60e0e800..4cd2dc1983 100644 --- a/module/zanode/model.php +++ b/module/zanode/model.php @@ -598,11 +598,7 @@ class zanodemodel extends model if($this->session->zanodeQuery == false) $this->session->set('zanodeQuery', ' 1 = 1'); } $query = $this->session->zanodeQuery; - $query = str_replace('`id`', 't1.`id`', $query); - $query = str_replace('`name`', 't1.`name`', $query); - $query = str_replace('`status`', 't1.`status`', $query); - $query = str_replace('`os`', 't1.`os`', $query); - $query = str_replace('`parent`', 't1.`parent`', $query); + $query = preg_replace('/`(id|name|status|os|parent|cpuCores|memory|diskSize|extranet)`/', 't1.`\1`', $query); $query = str_replace('`hostID`', 't2.`id`', $query); } From 4c6f5088e42c1e1d4c36e9ee019fcfcd12401577 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Thu, 16 Nov 2023 09:31:14 +0800 Subject: [PATCH 003/235] * Add redirect to implement after create if select implement,bug#38621. --- module/metric/js/browse.ui.js | 17 +++++++++++++++++ module/metric/zen.php | 14 +++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/module/metric/js/browse.ui.js b/module/metric/js/browse.ui.js index a3c95c2615..a789f55932 100644 --- a/module/metric/js/browse.ui.js +++ b/module/metric/js/browse.ui.js @@ -61,3 +61,20 @@ window.confirmEdit = function(metricID, isOldMetric) $(triggerClass).trigger('click'); } } + +window.getCurrentModal = function() +{ + target = zui.Modal.query().id; + target = `#${target}`; + + return zui.Modal.query(target); +} + +window.loadImplement = function(link) +{ + const modal = window.getCurrentModal(); + if(!modal) return; + + $("#" + modal.id).attr('load-url', link); + modal.render({url: link}); +} diff --git a/module/metric/zen.php b/module/metric/zen.php index 6681e5b65f..68465b748a 100644 --- a/module/metric/zen.php +++ b/module/metric/zen.php @@ -49,10 +49,18 @@ class metricZen extends metric * @access protected * @return array */ - protected function responseAfterCreate($scope) + protected function responseAfterCreate($metricID, $scope, $afterCreate) { - $location = $this->createLink('metric', 'browse', "scope=$scope"); - return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $location); + if($afterCreate == 'back') + { + $location = $this->createLink('metric', 'browse', "scope=$scope"); + return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $location); + } + + $closeModal = false; + $location = $this->createLink('metric', 'implement', "metricID=$metricID"); + $callback = array('name' => 'loadImplement', 'params' => $location); + return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'callback' => $callback); } /** From bc9a2cb0ef932ffae5462ad55a64ed155dde6209 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Thu, 16 Nov 2023 09:35:56 +0800 Subject: [PATCH 004/235] * Remove unique key of code in zt_metric. --- db/update18.8.sql | 2 ++ db/zentao.sql | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/db/update18.8.sql b/db/update18.8.sql index 707c43f7e8..4877bbbf51 100644 --- a/db/update18.8.sql +++ b/db/update18.8.sql @@ -82,3 +82,5 @@ UPDATE `zt_chart` SET `type` = 'cluBarY', `settings` = '[{\"type\":\"cluBarY\",\ UPDATE `zt_chart` SET `type` = 'cluBarY', `settings` = '[{\"type\":\"cluBarY\",\"xaxis\":[{\"field\":\"deptName\",\"name\":\"deptName\",\"group\":\"\"}],\"yaxis\":[{\"field\":\"count\",\"name\":\"count\",\"valOrAgg\":\"sum\"}]}]', `fields` = '{\"deptName\":{\"name\":\"deptName\",\"object\":\"false\",\"field\":\"deptName\",\"type\":\"object\"},\"count\":{\"name\":\"count\",\"object\":\"false\",\"field\":\"count\",\"type\":\"object\"},\"deptOrder\":{\"name\":\"deptOrder\",\"object\":\"false\",\"field\":\"deptOrder\",\"type\":\"object\"}}', `langs` = '{\"deptName\":{\"zh-cn\":\"\\u90e8\\u95e8\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"},\"count\":{\"zh-cn\":\"\\u4eba\\u6570\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"},\"deptOrder\":{\"zh-cn\":\"\\u987a\\u5e8f\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"}}', `sql` = 'SELECT IF(t3.id IS NOT NULL, t3.`name`, \"空\") AS deptName,count(1) as count, \nIF(t3.id IS NOT NULL, t3.`order`, 9999) AS deptOrder \nFROM zt_user AS t1 \nLEFT JOIN zt_dept AS t2 ON t1.dept = t2.id\nLEFT JOIN zt_dept AS t3 ON FIND_IN_SET(TRIM(\',\' FROM t3.path), TRIM(\',\' FROM t2.path)) AND t3.grade = \'1\'\nWHERE t1.deleted = \'0\'\nGROUP BY deptName, deptOrder \nORDER BY deptOrder ASC', `stage` = 'published', `builtin` = 0 WHERE `id` = 1049; UPDATE `zt_chart` SET `type` = 'pie', `settings` = '[{\"type\":\"pie\",\"group\":[{\"field\":\"role\",\"name\":\"\\u804c\\u4f4d\",\"group\":\"\"}],\"metric\":[{\"field\":\"account\",\"name\":\"\\u7528\\u6237\\u540d\",\"valOrAgg\":\"count\"}]}]', `fields` = '{\"account\":{\"name\":\"\\u7528\\u6237\\u540d\",\"object\":\"user\",\"field\":\"account\",\"type\":\"string\"},\"role\":{\"name\":\"\\u804c\\u4f4d\",\"object\":\"user\",\"field\":\"role\",\"type\":\"string\"}}', `langs` = '', `sql` = 'SELECT\n account,\nCASE\n ROLE \n WHEN \'dev\' THEN\n \"研发\" \n WHEN \'qa\' THEN\n \"测试\" \n WHEN \'pm\' THEN\n \"项目经理\" \n WHEN \'others\' THEN\n \"其他\" \n WHEN \'td\' THEN\n \"研发主管\" \n WHEN \'pd\' THEN\n \"产品主管\" \n WHEN \'po\' THEN\n \"产品经理\" \n WHEN \'qd\' THEN\n \"测试主管\" \n WHEN \'top\' THEN\n \"高层管理\" ELSE \"未知\" \n END role \nFROM\n zt_user \nWHERE\n deleted = \'0\'', `stage` = 'published', `builtin` = 0 WHERE `id` = 1050; UPDATE `zt_chart` SET `type` = 'cluBarY', `settings` = '[{\"type\":\"cluBarY\",\"xaxis\":[{\"field\":\"joinDate\",\"name\":\"joinDate\",\"group\":\"\"}],\"yaxis\":[{\"field\":\"count\",\"name\":\"count\",\"valOrAgg\":\"sum\"}]}]', `fields` = '{\"count\":{\"name\":\"count\",\"object\":\"user\",\"field\":\"count\",\"type\":\"string\"},\"joinDate\":{\"name\":\"joinDate\",\"object\":\"user\",\"field\":\"joinDate\",\"type\":\"string\"}}', `langs` = '{\"count\":{\"zh-cn\":\"\\u4eba\\u6570\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"},\"joinDate\":{\"zh-cn\":\"\\u5de5\\u9f84\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"}}', `sql` = 'SELECT count(1) as count, \"0-1年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 1 YEAR)\nunion\nSELECT count(1) as count, \"1-3年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 3 YEAR) AND `join` <= DATE_SUB(NOW(), INTERVAL 1 YEAR)\nunion\nSELECT count(1) as count, \"3-5年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 5 YEAR) AND `join` <= DATE_SUB(NOW(), INTERVAL 3 YEAR)\nunion\nSELECT count(1) as count, \"5-10年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 10 YEAR) AND `join` <= DATE_SUB(NOW(), INTERVAL 5 YEAR)\nunion\nSELECT count(1) as count, \"10年以上\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` < DATE_SUB(NOW(), INTERVAL 10 YEAR) AND LEFT(`join`, 4) != \'0000\'\nunion \nSELECT count(1) as count, \"未知\" as joinDate FROM zt_user WHERE deleted = \'0\' AND LEFT(`join`, 4) = \'0000\'', `stage` = 'published', `builtin` = 0 WHERE `id` = 1051; + +ALTER TABLE zt_metric DROP INDEX `code`; diff --git a/db/zentao.sql b/db/zentao.sql index c994a5d968..351d83a1f0 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -15929,7 +15929,6 @@ CREATE TABLE IF NOT EXISTS `zt_metric` ( `order` mediumint(8) unsigned NOT NULL DEFAULT '0', `deleted` enum('0','1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`), - UNIQUE KEY `code` (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_metriclib`; From ffe3bb1636c7ebcc9794352d795b1a55535116fb Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 09:51:09 +0800 Subject: [PATCH 005/235] * project: remove the formHidden widget because the formGroup widget will create a hidden input if set the disabled attribute of it. --- module/project/ui/create.html.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index f1cf2b9f94..d8381cd503 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -236,8 +236,7 @@ formPanel set::control(array('type' => 'radioList', 'inline' => true)), set::items($lang->project->multipleList), set::disabled($copyProjectID), - set::value('1'), - $copyProjectID ? formHidden('multiple', $copyProject->multiple) : null + set::value($copyProject ? $copyProject->multiple : 1) ) : null, formGroup ( From 8f471e51abfc043e71a9f749925ba53f2a77518c Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 09:55:41 +0800 Subject: [PATCH 006/235] * project: change the required attribute in form configuration of the end field to true. --- module/project/config/form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/project/config/form.php b/module/project/config/form.php index befb7a1f76..07934d736f 100644 --- a/module/project/config/form.php +++ b/module/project/config/form.php @@ -19,7 +19,7 @@ $config->project->form->create['PM'] = array('type' => 'string', 'requir $config->project->form->create['budget'] = array('type' => 'string', 'required' => false, 'default' => ''); $config->project->form->create['budgetUnit'] = array('type' => 'string', 'required' => false, 'default' => 'CNY'); $config->project->form->create['begin'] = array('type' => 'date', 'required' => true); -$config->project->form->create['end'] = array('type' => 'date', 'required' => false, 'default' => null); +$config->project->form->create['end'] = array('type' => 'date', 'required' => true, 'default' => null); $config->project->form->create['days'] = array('type' => 'int', 'required' => false, 'default' => 0); $config->project->form->create['desc'] = array('type' => 'string', 'required' => false, 'default' => '', 'control' => 'editor'); $config->project->form->create['acl'] = array('type' => 'string', 'required' => false, 'default' => ''); From 9a43a97894302e175cb64bbe518fa0c40d84cb81 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 10:13:23 +0800 Subject: [PATCH 007/235] * Code formatter for tutorial. --- module/tutorial/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/tutorial/model.php b/module/tutorial/model.php index 53b7a39271..73f8996b7c 100644 --- a/module/tutorial/model.php +++ b/module/tutorial/model.php @@ -24,7 +24,7 @@ class tutorialModel extends model if($account == 'guest') return false; if(!empty($this->app->user->modifyPassword)) return false; - $count = $this->dao->select('count(*) as count')->from(TABLE_ACTION)->where('actor')->eq($account)->fetch('count'); + $count = $this->dao->select('count(*) AS count')->from(TABLE_ACTION)->where('actor')->eq($account)->fetch('count'); if($count < 10) return true; $this->loadModel('setting')->setItem($account . '.common.global.novice', 0); From 79df1fcb26376f71f2a663e4d3c87674eb63abd7 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 16 Nov 2023 10:18:23 +0800 Subject: [PATCH 008/235] * Fix bug of search. --- module/build/ui/view.html.php | 2 +- module/company/ui/dynamic.html.php | 2 +- module/productplan/config.php | 17 ----------------- module/productplan/config/search.php | 18 ++++++++++++++++++ module/productplan/ui/view.html.php | 2 +- module/testtask/ui/linkcase.html.php | 2 +- module/testtask/zen.php | 2 +- 7 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 module/productplan/config/search.php diff --git a/module/build/ui/view.html.php b/module/build/ui/view.html.php index 021fad58a7..36cf177a32 100644 --- a/module/build/ui/view.html.php +++ b/module/build/ui/view.html.php @@ -270,7 +270,7 @@ detailBody ) : null ), h::hr(set::className('mt-6')), - history() + history(set::objectID($build->id)) ) ) ) diff --git a/module/company/ui/dynamic.html.php b/module/company/ui/dynamic.html.php index ccaea525f8..87f0681518 100644 --- a/module/company/ui/dynamic.html.php +++ b/module/company/ui/dynamic.html.php @@ -83,7 +83,7 @@ featureBar on::change('changeItem') ) ), - li(searchToggle(set::module('action'))) + li(searchToggle(set::module('action'), set::open($browseType == 'bysearch'))) ); $content = null; diff --git a/module/productplan/config.php b/module/productplan/config.php index 5050404266..76a9812683 100644 --- a/module/productplan/config.php +++ b/module/productplan/config.php @@ -17,23 +17,6 @@ $config->productplan->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#F $config->productplan->future = '2030-01-01'; global $app, $lang; -$config->productplan->search['module'] = 'productplan'; -$config->productplan->browse = new stdclass(); - -$config->productplan->search['fields']['title'] = $lang->productplan->title; -$config->productplan->search['fields']['id'] = $lang->productplan->id; -$config->productplan->search['fields']['branch'] = $lang->productplan->branch; -$config->productplan->search['fields']['status'] = $lang->productplan->status; -$config->productplan->search['fields']['begin'] = $lang->productplan->begin; -$config->productplan->search['fields']['end'] = $lang->productplan->end; - -$config->productplan->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => ''); -$config->productplan->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); -$config->productplan->search['params']['branch'] = array('operator' => 'include', 'control' => 'select', 'values' => ''); -$config->productplan->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->productplan->statusList); -$config->productplan->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->productplan->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); - $config->productplan->defaultFields['story'] = array('id', 'title', 'module', 'pri', 'status', 'openedBy', 'assignedTo', 'estimate', 'stage', 'actions'); $config->productplan->defaultFields['bug'] = array('id', 'title', 'pri', 'status', 'openedBy', 'assignedTo', 'actions'); $config->productplan->defaultFields['linkStory'] = array('id', 'pri', 'plan', 'module', 'title', 'openedBy', 'assignedTo', 'estimate', 'status', 'stage'); diff --git a/module/productplan/config/search.php b/module/productplan/config/search.php new file mode 100644 index 0000000000..b04d0c52b5 --- /dev/null +++ b/module/productplan/config/search.php @@ -0,0 +1,18 @@ +productplan->search['module'] = 'productplan'; + +$config->productplan->search['fields']['title'] = $lang->productplan->title; +$config->productplan->search['fields']['id'] = $lang->productplan->id; +$config->productplan->search['fields']['branch'] = $lang->productplan->branch; +$config->productplan->search['fields']['status'] = $lang->productplan->status; +$config->productplan->search['fields']['begin'] = $lang->productplan->begin; +$config->productplan->search['fields']['end'] = $lang->productplan->end; + +$config->productplan->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => ''); +$config->productplan->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); +$config->productplan->search['params']['branch'] = array('operator' => 'include', 'control' => 'select', 'values' => ''); +$config->productplan->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->productplan->statusList); +$config->productplan->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->productplan->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); + diff --git a/module/productplan/ui/view.html.php b/module/productplan/ui/view.html.php index 053ef71a56..4a813d79d0 100644 --- a/module/productplan/ui/view.html.php +++ b/module/productplan/ui/view.html.php @@ -267,7 +267,7 @@ detailBody item(set::name($lang->productplan->desc), empty($plan->desc) ? $lang->noData : html(($plan->desc))) ), h::hr(setClass('mt-4')), - history(set::commentBtn(false)) + history(set::objectID($plan->id), set::commentBtn(false)) ) ) ) diff --git a/module/testtask/ui/linkcase.html.php b/module/testtask/ui/linkcase.html.php index 05761e6e93..b527187e70 100644 --- a/module/testtask/ui/linkcase.html.php +++ b/module/testtask/ui/linkcase.html.php @@ -68,7 +68,7 @@ featureBar set::current($type), set::linkParams("taskID={$task->id}&type={key}"), to::before(backBtn(set::icon('back'), set::className('btn secondary'), $lang->goback)), - li(searchToggle()) + li(searchToggle(set::module('testcase'), set::open($type == 'bySearch'))) ); $footToolbar = array('items' => array diff --git a/module/testtask/zen.php b/module/testtask/zen.php index 460c56df64..567d3e99d4 100644 --- a/module/testtask/zen.php +++ b/module/testtask/zen.php @@ -81,7 +81,7 @@ class testtaskZen extends testtask $searchConfig = $this->config->testcase->search; $searchConfig['style'] = 'simple'; - $searchConfig['actionURL'] = inlink('linkcase', "taskID={$task->id}&type={$type}¶m={$param}"); + $searchConfig['actionURL'] = inlink('linkcase', "taskID={$task->id}&type=bySearch¶m={$param}"); $searchConfig['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($product->id, 'case', 0, $task->branch); $searchConfig['params']['scene']['values'] = $this->testcase->getSceneMenu($product->id); $searchConfig['params']['product']['values'] = array($product->id => $product->name); From eb78b78005735b53935351d4f81ccf3565d18c4c Mon Sep 17 00:00:00 2001 From: sunguangming Date: Thu, 16 Nov 2023 10:19:06 +0800 Subject: [PATCH 009/235] * Code for kanban details. --- module/execution/js/kanban.ui.js | 2 ++ module/kanban/js/view.ui.js | 2 ++ module/kanban/model.php | 4 ++-- module/story/tao.php | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/module/execution/js/kanban.ui.js b/module/execution/js/kanban.ui.js index 9a8c9417db..65551d77e6 100644 --- a/module/execution/js/kanban.ui.js +++ b/module/execution/js/kanban.ui.js @@ -541,6 +541,7 @@ window.fullScreen = function() var afterEnterFullscreen = function() { $('#kanbanList').addClass('fullscreen').css('background', '#fff'); + $('#kanbanList .kanban-list').css('height', '100%'); window.hideAllAction(); $.cookie.set('isFullScreen', 1); }; @@ -578,6 +579,7 @@ window.fullScreen = function() function exitFullScreen() { $('.btn').show(); + $('#kanbanList .kanban-list').css('height', 'calc(100vh - 120px)'); $.cookie.set('isFullScreen', 0); } diff --git a/module/kanban/js/view.ui.js b/module/kanban/js/view.ui.js index b41dc60217..0ca31d82bb 100644 --- a/module/kanban/js/view.ui.js +++ b/module/kanban/js/view.ui.js @@ -454,6 +454,7 @@ window.fullScreen = function() let afterEnterFullscreen = function() { $('#kanbanList').addClass('fullscreen').css('background', '#fff'); + $('#kanbanList .kanban-list').css('height', '100%'); window.hideAllAction(); $.cookie.set('isFullScreen', 1); }; @@ -491,6 +492,7 @@ window.fullScreen = function() function exitFullScreen() { $('.btn').show(); + $('#kanbanList .kanban-list').css('height', 'calc(100vh - 120px)'); $.cookie.set('isFullScreen', 0); } diff --git a/module/kanban/model.php b/module/kanban/model.php index 6ece023a26..5474618420 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1012,8 +1012,8 @@ class kanbanModel extends model if($groupBy != 'default' and $groupBy != '') { $regionData = array(); - $heading = new stdclass(); - $heading->title = $execution->name; + $heading = new stdclass(); + $heading->title = $execution->name; $heading->actions = $this->getRDRegionActions($executionID, $regionID); $regionData['key'] = "region{$executionID}"; diff --git a/module/story/tao.php b/module/story/tao.php index 11c8be25a5..af7d5a8bda 100644 --- a/module/story/tao.php +++ b/module/story/tao.php @@ -985,7 +985,7 @@ class storyTao extends storyModel $columnID = $this->loadModel('kanban')->getColumnIDByLaneID($laneID, 'backlog'); if(empty($columnID)) $columnID = zget($extra, 'columnID', 0); - if(!empty($laneID) && !empty($columnID)) $this->kanban->addKanbanCell($executionID, (int)$laneID, (int)$columnID, 'story', $storyID); + if(!empty($laneID) && !empty($columnID)) $this->kanban->addKanbanCell($executionID, (int)$laneID, (int)$columnID, 'story', (string)$storyID); if(empty($laneID) || empty($columnID)) $this->kanban->updateLane($executionID, 'story'); } From e48a2d683f019aaad7951e6a35e9bac1e90dbe76 Mon Sep 17 00:00:00 2001 From: wangyuting Date: Thu, 16 Nov 2023 02:21:49 +0000 Subject: [PATCH 010/235] * Fix load url bug on my work page of batch edit task. --- module/block/control.php | 1 + module/my/control.php | 2 +- module/task/zen.php | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/module/block/control.php b/module/block/control.php index 9e81e1584a..2aa1b3b8f4 100755 --- a/module/block/control.php +++ b/module/block/control.php @@ -323,6 +323,7 @@ class block extends control $blocksLayout = $this->post->block; $this->block->updateLayout($blocksLayout); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess)); } diff --git a/module/my/control.php b/module/my/control.php index 4784af0936..ec7ad4aff7 100755 --- a/module/my/control.php +++ b/module/my/control.php @@ -472,7 +472,7 @@ EOF; /* Save session. */ if($type != 'bySearch') $this->session->set('myTaskType', $type); - if($this->app->viewType != 'json') $this->session->set('taskList', $this->app->getURI(true), 'execution'); + if($this->app->viewType != 'json') $this->session->set('taskList', $this->app->getURI(true), 'my'); /* Load pager. */ $this->app->loadClass('pager', $static = true); diff --git a/module/task/zen.php b/module/task/zen.php index f6dc5d3834..33e9e334e8 100644 --- a/module/task/zen.php +++ b/module/task/zen.php @@ -1504,8 +1504,8 @@ class taskZen extends task */ protected function responseAfterBatchEdit(array $allChanges): array { - $response['result'] = 'success'; - $response['message'] = $this->lang->saveSuccess; + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; if(!empty($allChanges)) { From ea580be69944a900fd0a2b40e19a22148cbc1a68 Mon Sep 17 00:00:00 2001 From: wangyuting Date: Thu, 16 Nov 2023 02:29:02 +0000 Subject: [PATCH 011/235] * Fix my work sort of estimateLabel and consumedLabel and leftLabel bug. --- module/my/control.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/my/control.php b/module/my/control.php index ec7ad4aff7..3b941820a3 100755 --- a/module/my/control.php +++ b/module/my/control.php @@ -479,10 +479,11 @@ EOF; if($this->app->getViewType() == 'mhtml') $recPerPage = 10; $pager = pager::init($recTotal, $recPerPage, $pageID); - if(strpos($orderBy, 'estimateLabel') !== false || strpos($orderBy, 'consumedLabel') !== false || strpos($orderBy, 'leftLabel') !== false) $orderBy = str_replace('Label', '', $orderBy); + $realOrder = $orderBy; + if(strpos($orderBy, 'estimateLabel') !== false || strpos($orderBy, 'consumedLabel') !== false || strpos($orderBy, 'leftLabel') !== false) $realOrder = str_replace('Label', '', $realOrder); /* append id for second sort. */ - $sort = common::appendOrder($orderBy); + $sort = common::appendOrder($realOrder); /* Get tasks. */ if($type == 'assignedBy') From e2ab161debd9b290ddbf68f76f46e998755633a3 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 10:42:02 +0800 Subject: [PATCH 012/235] * Refactor programplan::edit. --- module/programplan/js/edit.ui.js | 64 ++++++++++++++++++--------- module/programplan/tao.php | 2 +- module/programplan/ui/edit.html.php | 68 ++++++++++++++--------------- 3 files changed, 76 insertions(+), 58 deletions(-) diff --git a/module/programplan/js/edit.ui.js b/module/programplan/js/edit.ui.js index 70980cf1dc..c437dcbe93 100644 --- a/module/programplan/js/edit.ui.js +++ b/module/programplan/js/edit.ui.js @@ -8,12 +8,22 @@ function changeParentStage(event) { const stageID = parseInt($(event.target).val()); - if(stageID == 0) $('#acl').attr('disabled', false); - $('#acl').attr('disabled', true); + $('#acl').attr('disabled', stageID != 0); - $.get($.createLink('programplan', 'ajaxGetAttribute', 'stageID=' + stageID + '&attribute=' + plan.attribute), function(attribute) + $.get($.createLink('programplan', 'ajaxGetStageAttr', 'stageID=' + stageID), function(attribute) { - $('#attributeType').html(attribute); + var isPicker = $('#attributeType').find('.picker-box').length > 0; + if((attribute.length == 0 || attribute == 'mix') && !isPicker) + { + $('#attributeType').empty().append('
'); + $('#attribute').picker({name: 'attribute', items: stageTypeItems, defaultValue: attribute}); + } + if(isPicker && attribute != 'mix' && attribute.length > 0) + { + $('#attributeType').find('[name=attribute]').zui('picker').destroy(); + $('#attributeType').find('.picker-box').remove(); + $('#attributeType').append('' + stageTypeList[attribute] + ''); + } }); } @@ -23,31 +33,43 @@ function changeParentStage(event) * * @return void */ -function editStage() +window.editStage = function() { - if(plan.parent != $('#parent').val() && $('#parent').val() != 0) + var result = true; + var currentParent = $('[name=parent]').val(); + if(plan.parent != currentParent && currentParent != 0) { - var result = true; - - $.get($.createLink('programplan', 'ajaxGetStageAttr', 'stageID=' + $('#parent').val()), function(attribute) + result = false; + $.get($.createLink('programplan', 'ajaxGetStageAttr', 'stageID=' + currentParent), function(attribute) { - if(attribute != 'mix' && plan.attribute != attribute) - { - result = confirm(changeAttrLang.replace('%s', stageTypeList[attribute])); - } + if(attribute != 'mix' && plan.attribute != attribute) zui.Modal.confirm(changeAttrLang.replace('%s', stageTypeList[attribute])).then((res) => + { + if(res) + { + var $form = $('#editForm'); + var formUrl = $form.attr('action'); + var formData = new FormData($form[0]); + $.ajaxSubmit({url: formUrl, data: formData}); + } + }); }); - - if(!result) return; } - var currentAttribute = $('#attribute').val(); - var currentParent = $('#parent').val(); + var currentAttribute = $('[name=attribute]').val(); var hasChangedAttribute = (currentAttribute && currentAttribute != 'mix' && plan.attribute != currentAttribute); - var hasChangedParent = ((isTopStage && $('#parent').val() != 0) || (!isTopStage && plan.parent != $('#parent').val())); + var hasChangedParent = ((isTopStage && currentParent != 0) || (!isTopStage && plan.parent != currentParent)); if(hasChangedAttribute && !hasChangedParent && !isLeafStage) { - var result = confirm(changeAttrLang.replace('%s', stageTypeList[currentAttribute])); - - if(!result) return; + zui.Modal.confirm(changeAttrLang.replace('%s', stageTypeList[currentAttribute])).then((res) => + { + if(res) + { + var $form = $('#editForm'); + var formUrl = $form.attr('action'); + var formData = new FormData($form[0]); + $.ajaxSubmit({url: formUrl, data: formData}); + } + }); } + return result; } diff --git a/module/programplan/tao.php b/module/programplan/tao.php index 8e2e2cb786..c5a5b1c4d6 100644 --- a/module/programplan/tao.php +++ b/module/programplan/tao.php @@ -153,7 +153,7 @@ class programplanTao extends programplanModel return false; } - if($projectID) $this->loadModel('execution')->checkBeginAndEndDate($projectID, $plan->begin, $plan->end); + if($projectID) $this->loadModel('execution')->checkBeginAndEndDate($projectID, $plan->begin, $plan->end, $plan->parent); if(dao::isError()) return false; $setCode = isset($this->config->setCode) && $this->config->setCode == 1; diff --git a/module/programplan/ui/edit.html.php b/module/programplan/ui/edit.html.php index 1b80e19789..9bb24a6695 100644 --- a/module/programplan/ui/edit.html.php +++ b/module/programplan/ui/edit.html.php @@ -11,9 +11,12 @@ declare(strict_types=1); */ namespace zin; -$typeList = $project->model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList; +$typeList = $project->model == 'ipd' ? $lang->stage->ipdTypeList : $lang->stage->typeList; +$typeItems = array(); +foreach($typeList as $key => $value) $typeItems[] = array('text' => $value, 'value' => $key); jsVar('plan', $plan); jsVar('stageTypeList', $typeList); +jsVar('stageTypeItems', $typeItems); jsVar('changeAttrLang', $lang->programplan->confirmChangeAttr); jsVar('isTopStage', $isTopStage); jsVar('isLeafStage', $isLeafStage); @@ -27,6 +30,8 @@ modalHeader formPanel ( + set::id('editForm'), + set::ajax(array('beforeSubmit' => jsRaw("editStage"))), set::submitBtnText($lang->save), formGroup ( @@ -49,8 +54,7 @@ formPanel set::required(true), input(set::name('name'), set::value($plan->name)) ), - isset($config->setCode) && $config->setCode == 1 ? - formGroup + isset($config->setCode) && $config->setCode == 1 ? formGroup ( set::label($lang->execution->code), set::width('1/2'), @@ -91,33 +95,24 @@ formPanel ( setID('attributeType'), setClass('flex self-center w-full'), - $enableOptionalAttr ? - select(set(array( - 'id' => 'attribute', - 'name' => 'attribute', - 'items' => $typeList, - 'value' => $plan->attribute, - 'required' => true - ))) : zget($typeList, $plan->attribute) + $enableOptionalAttr ? picker + ( + set::id('attribute'), + set::name('attribute'), + set::items($typeList), + set::value($plan->attribute), + set::required(true) + ) : zget($typeList, $plan->attribute), ) ), formGroup ( - btn(set(array( - 'icon' => 'help', - 'data-toggle' => 'tooltip', - 'data-placement' => 'right', - 'href' => 'helpTip', - 'class' => 'ghost h-8 tooltip-btn' - ))), - div + setClass('items-center'), + icon ( - $lang->execution->typeTip, - setClass('w-1/3'), - set(array( - 'id' => 'helpTip', - 'class' => 'tooltip darker' - )) + 'help', + toggle::tooltip(array('title' => $lang->execution->typeTip, 'placement' => 'right')), + setClass('ghost ml-1') ) ) ), @@ -148,7 +143,7 @@ formPanel ( set::label($lang->project->acl), set::width('1/2'), - select + picker ( set::name('acl'), set::items($lang->execution->aclList), @@ -157,12 +152,12 @@ formPanel set::required(true) ) ), - $plan->setMilestone ? - formGroup + $plan->setMilestone ? formGroup ( set::label($lang->programplan->milestone), set::width('1/2'), - radioList( + radioList + ( set::name('milestone'), set::items($lang->programplan->milestoneList), set::value($plan->milestone), @@ -174,13 +169,14 @@ formPanel ( set::label($lang->programplan->output), set::width('1/2'), - select(set(array( - 'name' => 'output[]', - 'items' => $documentList, - 'value' => $plan->output, - 'multiple' => true, - 'required' => true - ))) + picker + ( + set::name('output[]'), + set::items($documentList), + set::value($plan->output), + set::multiple(true), + set::required(true) + ) ) : null ); From 4303384413e4b230f454d9223d5ce9fe44aa1acb Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 10:55:04 +0800 Subject: [PATCH 013/235] + Add `data-app` to title in product::browse. --- module/product/config/dtable.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/product/config/dtable.php b/module/product/config/dtable.php index 91b64e83d4..9e2e630128 100644 --- a/module/product/config/dtable.php +++ b/module/product/config/dtable.php @@ -12,6 +12,7 @@ $config->product->dtable->fieldList['name']['sortType'] = true; $config->product->dtable->fieldList['name']['align'] = 'left'; $config->product->dtable->fieldList['name']['border'] = 'right'; $config->product->dtable->fieldList['name']['link'] = helper::createLink('product', 'browse', "productID={id}"); +$config->product->dtable->fieldList['name']['data-app'] = $app->tab; $config->product->dtable->fieldList['productLine']['name'] = 'productLine'; $config->product->dtable->fieldList['productLine']['title'] = $lang->product->belongingLine; From bae475955aea1971340f8b55253886c7da4fe777 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 11:04:32 +0800 Subject: [PATCH 014/235] * Change multiple task assinged to link. --- module/execution/control.php | 15 +++++++++++++++ module/execution/js/task.ui.js | 9 ++++++++- module/execution/ui/task.html.php | 1 + module/task/control.php | 7 +++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/module/execution/control.php b/module/execution/control.php index 28a8cbaaff..6253801ed1 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -166,9 +166,24 @@ class execution extends control $memberPairs = $this->loadModel('user')->processAccountSort($memberPairs); /* Append branches to task. */ + $this->loadModel('task'); $branchGroups = $this->loadModel('branch')->getByProducts(array_keys($this->view->products)); foreach($tasks as $task) { + if($task->mode == 'multi' && strpos('done,closed', $task->status) === false) + { + $task->assignedTo = ''; + + $taskTeam = $this->task->getTeamByTask($task->id); + foreach($taskTeam as $teamMember) + { + if($this->app->user->account == $teamMember->account and $teamMember->status != 'done') + { + $task->assignedTo = $this->app->user->account; + break; + } + } + } if(isset($branchGroups[$task->product][$task->branch])) $task->branch = $branchGroups[$task->product][$task->branch]; } diff --git a/module/execution/js/task.ui.js b/module/execution/js/task.ui.js index 3971fffd53..994a1d6688 100644 --- a/module/execution/js/task.ui.js +++ b/module/execution/js/task.ui.js @@ -93,9 +93,9 @@ window.setStatistics = function(element, checkedIDList) */ window.renderCell = function(result, info) { + const task = info.row.data; if(info.col.name == 'name' && result) { - const task = info.row.data; let html = ''; const module = this.options.modules[info.row.data.module]; @@ -128,5 +128,12 @@ window.renderCell = function(result, info) result[0] = {html: '' + result[0] + ''}; } } + if(info.col.name == 'assignedTo' && result) + { + if(!task.assignedTo && task.mode == 'multi' && !['done,closed'].includes(task.status)) + { + result[0]['props']['children'][1]['props']['children'] = teamLang; + } + } return result; } diff --git a/module/execution/ui/task.html.php b/module/execution/ui/task.html.php index 0293670e3e..ec3ccea10a 100644 --- a/module/execution/ui/task.html.php +++ b/module/execution/ui/task.html.php @@ -162,6 +162,7 @@ jsVar('multipleAB', $lang->task->multipleAB); jsVar('childrenAB', $lang->task->childrenAB); jsVar('todayLabel', $lang->today); jsVar('yesterdayLabel', $lang->yesterday); +jsVar('teamLang', $lang->task->team); dtable ( diff --git a/module/task/control.php b/module/task/control.php index 58f27535a9..e814b86cb4 100755 --- a/module/task/control.php +++ b/module/task/control.php @@ -243,6 +243,13 @@ class task extends control { $this->taskZen->commonAction($taskID); + $task = $this->task->getByID($taskID); + if(!empty($task->team) && $task->mode == 'multi' && strpos('done,cencel,closed', $task->status) === false) + { + echo $this->fetch('task', 'manageTeam', "executionID=$executionID&taskID=$taskID&from=$from"); + return; + } + if(!empty($_POST)) { $task = form::data($this->config->task->form->assign) From cb762c86532d68e470c3d24da349e18b1094c37d Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 11:04:52 +0800 Subject: [PATCH 015/235] * Move the getTeamByTask method into model.php. --- module/task/model.php | 16 +++++++++++++++- module/task/tao.php | 14 -------------- .../task/test/{tao => model}/getteambytask.php | 0 3 files changed, 15 insertions(+), 15 deletions(-) rename module/task/test/{tao => model}/getteambytask.php (100%) diff --git a/module/task/model.php b/module/task/model.php index 7af46bb304..774342f29d 100755 --- a/module/task/model.php +++ b/module/task/model.php @@ -1231,7 +1231,7 @@ class taskModel extends model if(!empty($task->mode)) { $task->members = array(); - $task->team = $this->taskTao->getTeamByTask($taskID); + $task->team = $this->getTeamByTask($taskID); foreach($task->team as $member) $task->members[$member->account] = $member->account; } else @@ -3140,4 +3140,18 @@ class taskModel extends model ->andWhere('AID')->eq($taskID) ->fetchPairs(); } + + /** + * 通过任务ID获取任务团队信息。 + * Get the task team information through the task ID. + * + * @param int $taskID + * @param string $orderBy + * @access protected + * @return object[] + */ + public function getTeamByTask(int $taskID, string $orderBy = 'order_asc'): array + { + return $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->orderBy($orderBy)->fetchAll('id'); + } } diff --git a/module/task/tao.php b/module/task/tao.php index 88ab773b41..ac21617cd0 100644 --- a/module/task/tao.php +++ b/module/task/tao.php @@ -889,20 +889,6 @@ class taskTao extends taskModel return trim($requiredFields, ','); } - /** - * 通过任务ID获取任务团队信息。 - * Get the task team information through the task ID. - * - * @param int $taskID - * @param string $orderBy - * @access protected - * @return object[] - */ - protected function getTeamByTask(int $taskID, string $orderBy = 'order_asc'): array - { - return $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->orderBy($orderBy)->fetchAll('id'); - } - /** * 获取团队成员以及他的预计、消耗、剩余工时。 * Get team account,estimate,consumed and left info. diff --git a/module/task/test/tao/getteambytask.php b/module/task/test/model/getteambytask.php similarity index 100% rename from module/task/test/tao/getteambytask.php rename to module/task/test/model/getteambytask.php From 7e25aa8a2016b9c9b16c994802aec89084c4b9c9 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 11:20:47 +0800 Subject: [PATCH 016/235] + Add title color of the task list. --- module/task/config/dtable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/task/config/dtable.php b/module/task/config/dtable.php index 11a48a4b9f..518e7536bc 100644 --- a/module/task/config/dtable.php +++ b/module/task/config/dtable.php @@ -12,9 +12,9 @@ $config->task->dtable->fieldList['name']['flex'] = 1; $config->task->dtable->fieldList['name']['type'] = 'nestedTitle'; $config->task->dtable->fieldList['name']['nestedToggle'] = true; $config->task->dtable->fieldList['name']['sortType'] = true; -$config->task->dtable->fieldList['name']['link'] = array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}'); +$config->task->dtable->fieldList['name']['link'] = array('url' => array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}'), 'className' => 'text-inherit'); $config->task->dtable->fieldList['name']['required'] = true; -$config->task->dtable->fieldList['name']['color'] = true; +$config->task->dtable->fieldList['name']['styleMap'] = array('color' => 'color'); $config->task->dtable->fieldList['pri']['title'] = $lang->priAB; $config->task->dtable->fieldList['pri']['type'] = 'pri'; From 649249338dfc0071d564c26d3f3d80549943c791 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Thu, 16 Nov 2023 11:20:49 +0800 Subject: [PATCH 017/235] * Add card type in execution kanban. --- module/kanban/model.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/kanban/model.php b/module/kanban/model.php index 5474618420..9f65b9412b 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1962,6 +1962,7 @@ class kanbanModel extends model $cardData = $this->buildExecutionCard($object, $column, $browseType, $searchValue, $menus); if(empty($cardData)) continue; + $cardData['cardType'] = $browseType; if($groupBy == 'assignedTo' && $object->$groupBy !== $laneID) $cardData['assignedTo'] = $laneID; if($cardData['assignedTo']) { From 8926f44b2bfea441253aa42b20b446b6e8f315d8 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 11:23:56 +0800 Subject: [PATCH 018/235] * Set module link in bug::view. --- module/bug/ui/view.html.php | 29 +++++++++++++++++++++++++++++ module/bug/zen.php | 19 +------------------ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/module/bug/ui/view.html.php b/module/bug/ui/view.html.php index f984ca92f1..b402a8cee4 100644 --- a/module/bug/ui/view.html.php +++ b/module/bug/ui/view.html.php @@ -21,6 +21,35 @@ $canViewRepo = hasPriv('repo', 'revision'); $canViewMR = hasPriv('mr', 'view'); $canViewBug = hasPriv('bug', 'view'); +$moduleHTML = array(); +$moduleTitle = ''; +$moduleItems = array(); +if(empty($modulePath)) +{ + $moduleTitle .= '/'; + $moduleItems[] = span('/'); +} +else +{ + if($bug->branch and isset($branches[$bug->branch])) + { + $moduleTitle .= $branches[$bug->branch] . '/'; + $moduleItems[] = span($branches[$bug->branch], icon('angle-right')); + } + + foreach($modulePath as $key => $module) + { + $moduleTitle .= $module->name; + $moduleItems[] = $product->shadow ? span($module->name) : a(set::href(helper::createLink('bug', 'browse', "productID=$bug->product&branch=$bug->branch&browseType=byModule¶m=$module->id")), $module->name); + if(isset($modulePath[$key + 1])) + { + $moduleTitle .= '/'; + $moduleItems[] = icon('angle-right'); + } + } +} +$legendBasic['module']['text'] = $moduleItems; + $buildsHTML = array(); $openedBuilds = explode(',', $legendLife['openedBuild']['text']); foreach($openedBuilds as $openedBuild) diff --git a/module/bug/zen.php b/module/bug/zen.php index b68b25fc92..fa876beb36 100644 --- a/module/bug/zen.php +++ b/module/bug/zen.php @@ -594,23 +594,6 @@ class bugZen extends bug $canViewPlan = common::hasPriv('productplan', 'view'); $canViewCase = common::hasPriv('testcase', 'view'); - $moduleTitle = ''; - if(empty($modulePath)) - { - $moduleTitle .= '/'; - } - else - { - if($bugModule->branch && isset($branches[$bugModule->branch])) $moduleTitle .= $branches[$bugModule->branch] . '/'; - - foreach($modulePath as $key => $module) - { - $moduleTitle .= $module->name; - - if(isset($modulePath[$key + 1])) $moduleTitle .= '/'; - } - } - $branchTitle = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]); $fromCaseName = $bug->case ? "#{$bug->case} {$bug->caseTitle}" : ''; $productLink = $bug->product && $canViewProduct ? helper::createLink('product', 'view', "productID={$bug->product}") : ''; @@ -621,7 +604,7 @@ class bugZen extends bug $legendBasic = array(); if(empty($product->shadow)) $legendBasic['product'] = array('name' => $this->lang->bug->product, 'text' => $product->name, 'href' => $productLink, 'attr' => array('data-app' => 'product')); if($product->type != 'normal') $legendBasic['branch'] = array('name' => $branchTitle, 'text' => $branchName, 'href' => $branchLink); - $legendBasic['module'] = array('name' => $this->lang->bug->module, 'text' => $moduleTitle); + $legendBasic['module'] = array('name' => $this->lang->bug->module, 'text' => $bug->module); if(empty($product->shadow) || !empty($project->multiple)) $legendBasic['productplan'] = array('name' => $this->lang->bug->plan, 'text' => $bug->planName, 'href' => $planLink); $legendBasic['fromCase'] = array('name' => $this->lang->bug->fromCase, 'text' => $fromCaseName, 'href' => $fromCaseLink, 'attr' => array('data-toggle' => 'modal', 'data-size' => 'lg')); $legendBasic['type'] = array('name' => $this->lang->bug->type, 'text' => zget($this->lang->bug->typeList, $bug->type)); From 655d1abccf0400fa39d16f272adb0e7b815f068b Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 11:25:13 +0800 Subject: [PATCH 019/235] * Use icon to separate module. --- module/testcase/ui/view.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/testcase/ui/view.html.php b/module/testcase/ui/view.html.php index 0ae4ef828d..a34771e542 100644 --- a/module/testcase/ui/view.html.php +++ b/module/testcase/ui/view.html.php @@ -164,7 +164,7 @@ else { $moduleItems[] = $module->name; } - if(isset($modulePath[$key + 1])) $moduleItems[] = ' / '; + if(isset($modulePath[$key + 1])) $moduleItems[] = icon('angle-right'); } } From fb2dd2057ae91e0679ca916c517d380d83d97c74 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Thu, 16 Nov 2023 13:12:27 +0800 Subject: [PATCH 020/235] Revert "* Fix browse sidebar style." This reverts commit ef7ae8e70dd61b31dc902973b1516111a705e931. --- module/metric/css/browse.ui.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/module/metric/css/browse.ui.css b/module/metric/css/browse.ui.css index 37b5daaf9a..f1fbdfdbf0 100644 --- a/module/metric/css/browse.ui.css +++ b/module/metric/css/browse.ui.css @@ -15,5 +15,3 @@ .clear-gap {gap: 0 !important;} .dtable-cell-html {width: inherit;} .dtable-name-flex {display: flex; justify-content: space-between;} - -#mainMenu+#mainContent>.sidebar-left {margin-top: 0;} From a23033ab5c24f841dc0b22fdcf36988a6bf5109e Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 13:17:52 +0800 Subject: [PATCH 021/235] * Set object id of history widget in testreport::view. --- module/testreport/ui/view.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/testreport/ui/view.html.php b/module/testreport/ui/view.html.php index 6940f5d024..0772e8f7c9 100644 --- a/module/testreport/ui/view.html.php +++ b/module/testreport/ui/view.html.php @@ -383,7 +383,7 @@ div set::fieldset(false) ) ) : null, - history() + history(set::objectID($report->id)) ) ), tabPane From 4ad154c95429a9e79439593dad4e754d62065610 Mon Sep 17 00:00:00 2001 From: songchenxuan Date: Thu, 16 Nov 2023 11:53:39 +0800 Subject: [PATCH 022/235] * Merge commit d60bbd6fc5, fix bug #40588. --- .../calc/user/scale/count_of_daily_review_feedback_in_user.php | 3 +++ .../calc/user/scale/count_of_daily_review_story_in_user.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/module/metric/calc/user/scale/count_of_daily_review_feedback_in_user.php b/module/metric/calc/user/scale/count_of_daily_review_feedback_in_user.php index f03ebf9125..11f62eb8b3 100755 --- a/module/metric/calc/user/scale/count_of_daily_review_feedback_in_user.php +++ b/module/metric/calc/user/scale/count_of_daily_review_feedback_in_user.php @@ -33,6 +33,9 @@ class count_of_daily_review_feedback_in_user extends baseCalc if(empty($reviewedDate) || empty($reviewedBy)) return false; + /* input ,admin output admin */ + $reviewedBy = current(array_filter(explode(',', $reviewedBy))); + $year = substr($reviewedDate, 0, 4); if($year == '0000') return false; diff --git a/module/metric/calc/user/scale/count_of_daily_review_story_in_user.php b/module/metric/calc/user/scale/count_of_daily_review_story_in_user.php index aa4cf1de52..09a177cf34 100755 --- a/module/metric/calc/user/scale/count_of_daily_review_story_in_user.php +++ b/module/metric/calc/user/scale/count_of_daily_review_story_in_user.php @@ -33,6 +33,9 @@ class count_of_daily_review_story_in_user extends baseCalc if(empty($reviewedDate) || empty($reviewedBy)) return false; + /* input ,admin output admin */ + $reviewedBy = current(array_filter(explode(',', $reviewedBy))); + $year = substr($reviewedDate, 0, 4); if($year == '0000') return false; From ce82369b02469888b2774db548c97aa7d6aaefae Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 13:33:42 +0800 Subject: [PATCH 023/235] * View task in execution. --- module/my/config/table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/my/config/table.php b/module/my/config/table.php index 1234c37bce..ef51f11854 100644 --- a/module/my/config/table.php +++ b/module/my/config/table.php @@ -222,7 +222,7 @@ $config->my->task->dtable->fieldList['name']['name'] = 'name'; $config->my->task->dtable->fieldList['name']['title'] = $lang->task->name; $config->my->task->dtable->fieldList['name']['type'] = 'title'; $config->my->task->dtable->fieldList['name']['nestedToggle'] = true; -$config->my->task->dtable->fieldList['name']['link'] = array('url' => array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}'), 'data-app' => 'project'); +$config->my->task->dtable->fieldList['name']['link'] = array('url' => array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}'), 'data-app' => 'execution'); $config->my->task->dtable->fieldList['name']['fixed'] = 'left'; $config->my->task->dtable->fieldList['name']['sortType'] = true; From 179981803dac3d28cd6cad91033433d91109479c Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 13:36:07 +0800 Subject: [PATCH 024/235] * Set object id to history in caselib::view. --- module/caselib/ui/view.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/caselib/ui/view.html.php b/module/caselib/ui/view.html.php index 2974627ece..5c465e8019 100644 --- a/module/caselib/ui/view.html.php +++ b/module/caselib/ui/view.html.php @@ -34,7 +34,7 @@ detailBody set::content($lib->desc), set::useHtml(true) ), - history() + history(set::objectID($lib->id)) ), floatToolbar ( From 1ed7261e732611389759ec88e59842c6075ec426 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 16 Nov 2023 13:39:59 +0800 Subject: [PATCH 025/235] * Fix bug of finish task. --- module/task/ui/finish.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/task/ui/finish.html.php b/module/task/ui/finish.html.php index aea84ad2a7..7d01d80b79 100644 --- a/module/task/ui/finish.html.php +++ b/module/task/ui/finish.html.php @@ -149,7 +149,7 @@ else set::value($realStarted), set('disabled', !empty($realStarted)) ), - formHidden('realStarted', $realStarted) + !empty($realStarted) ? formHidden('realStarted', $realStarted) : null ), formGroup ( From b64330721c0c4064b6af580d327c43e8a27c0829 Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 05:42:40 +0000 Subject: [PATCH 026/235] * Adjust use items when change type. * Toggle the user info when click new user button. --- module/stakeholder/control.php | 15 ++++- module/stakeholder/js/create.ui.js | 67 ++++++--------------- module/stakeholder/ui/create.html.php | 84 +++++++++++++-------------- 3 files changed, 68 insertions(+), 98 deletions(-) diff --git a/module/stakeholder/control.php b/module/stakeholder/control.php index 0b7512b42e..21ede72b2c 100644 --- a/module/stakeholder/control.php +++ b/module/stakeholder/control.php @@ -212,7 +212,10 @@ class stakeholder extends control if(isset($stakeholders[$account])) unset($members[$account]); } - echo html::select('user', $members, $user, "class='form-control chosen'"); + $items = array(); + foreach($members as $account => $realname) $items[] = array('key' => $account, 'text' => $realname); + + return print(json_encode($items)); } /** @@ -243,7 +246,10 @@ class stakeholder extends control if(isset($stakeholders[$account])) unset($companyUsers[$account]); } - echo html::select('user', $companyUsers, $user, "class='form-control chosen'"); + $userItems = array(); + foreach($companyUsers as $account => $realname) $userItems[] = array('text' => $realname, 'key' => $account); + + return print(json_encode($userItems)); } /** @@ -261,7 +267,10 @@ class stakeholder extends control if(isset($stakeholders[$account])) unset($users[$account]); } - echo html::select('user', $users, '', "class='form-control chosen' onchange=changeUser(this.value);"); + $items = array(); + foreach($users as $account => $realname) $items[] = array('text' => $realname, 'key' => $account); + + return print(json_encode($items)); } /** diff --git a/module/stakeholder/js/create.ui.js b/module/stakeholder/js/create.ui.js index f5c1ab9936..e1f7a08895 100644 --- a/module/stakeholder/js/create.ui.js +++ b/module/stakeholder/js/create.ui.js @@ -3,63 +3,30 @@ * * @return void */ -function onChangeStakeholderType(event) +function toggleUser() { - if($(event.target).val() === 'outside') + if($(this).val() == 'team') var link = $.createLink('stakeholder', 'ajaxGetMembers', 'user=&program=' + programID + '&projectID=' + projectID); + if($(this).val() == 'company') var link = $.createLink('stakeholder', 'ajaxGetCompanyUser', 'user=&programID=' + programID + '&projectID=' + projectID); + if($(this).val() == 'outside') var link = $.createLink('stakeholder', 'ajaxGetOutsideUser', 'objectID=' + programID ? programID : projectID); + $.getJSON(link, function(users) { - toggleNewUserCheckbox(true); - return; - } + let $userPicker = $('[name^="user"]').zui('picker'); + $userPicker.render({items: users}); + $userPicker.$.setValue(''); + }); - toggleNewUserCheckbox(false); + $('[name=newUser]').prop('checked', false); + $('[name=newUser]').parents('.input-group-addon').toggleClass('hidden', $(this).val() != 'outside'); + + toggleNewUserInfo(); } -/* - * 显示新建用户选择框。 - * - * @return void - */ -function toggleNewUserCheckbox(remove) +function toggleNewUserInfo() { - const elements = $('.newuser-checkbox'); - if(remove) - { - elements.removeClass('hidden'); - return; - } + let $userPicker = $('[name^="user"]').zui('picker'); + $userPicker.render({disabled: $('[name=newUser]').prop('checked')}); - elements.addClass('hidden'); -} - -/** - * 新建用户选择框变更回调函数。 - * - * @return void - */ -function onChangeNewUserCheckbox(event) -{ - const checked = $(event.target).prop('checked'); - - toggleUserInfo(checked); - - $('#user').prop('disabled', checked); -} - -/** - * 显示新建用户信息输入框。 - * - * @return void - */ -function toggleUserInfo(remove) -{ - const elements = $('.user-info'); - if(remove) - { - elements.removeClass('hidden'); - return; - } - - elements.addClass('hidden'); + $('.user-info').toggleClass('hidden', !$('[name=newUser]').prop('checked')); } /** diff --git a/module/stakeholder/ui/create.html.php b/module/stakeholder/ui/create.html.php index a1ea47dbaf..41e6d5e6ed 100644 --- a/module/stakeholder/ui/create.html.php +++ b/module/stakeholder/ui/create.html.php @@ -13,8 +13,20 @@ namespace zin; dropmenu(); +jsVar('projectID', $projectID); +jsVar('programID', $programID); + +$fromItems = array(); +foreach($lang->stakeholder->fromList as $fromKey => $fromName) $fromItems[] = array('text' => $fromName, 'value' => $fromKey); + +$keyItems = array(); +foreach($lang->stakeholder->keyList as $key => $keyName) $keyItems[] = array('text' => $keyName, 'value' => $key); + formPanel ( + on::change('[name=from]', 'toggleUser'), + on::change('[name=newUser]', 'toggleNewUserInfo'), + on::change('[name=new]', 'onChooseCompany'), set::url(createLink('stakeholder', 'create', "objectID=$objectID")), to::heading(div ( @@ -25,44 +37,24 @@ formPanel ( set::label($lang->stakeholder->from), set::width('1/2'), - inputGroup(array_map + radioList ( - function($val, $text) - { - return radio - ( - set::name('from'), - set::value($val), - set::text($text), - set::checked($val == 'team'), - on::change('onChangeStakeholderType') - ); - }, - array_keys($lang->stakeholder->fromList), - array_values($lang->stakeholder->fromList) - )) + set::name('from'), + set::value('team'), + set::inline(true), + set::items($fromItems) + ) ), formGroup ( set::label($lang->stakeholder->isKey), set::width('1/2'), - inputGroup + radioList ( - array_map - ( - function($val, $text) - { - return radio - ( - set::name('key'), - set::value($val), - set::text($text), - set::checked($val == 0) - ); - }, - array_keys($lang->stakeholder->keyList), - array_values($lang->stakeholder->keyList) - ) + set::name('key'), + set::value('0'), + set::inline(true), + set::items($keyItems) ) ), formRow(formGroup @@ -77,12 +69,14 @@ formPanel set::name('user'), set::items($members) ), - checkbox + span ( - set::rootClass('newuser-checkbox hidden w-20 justify-end items-center'), - set::name('newUser'), - on::click('onChangeNewUserCheckbox'), - set::text($lang->stakeholder->add) + setClass('input-group-addon hidden'), + checkbox + ( + set::name('newUser'), + set::text($lang->stakeholder->add) + ) ) ) )), @@ -144,24 +138,24 @@ formPanel set::required(true), inputGroup ( - select + picker ( set::name('companySelect'), - set::items($companys), - on::change('onChooseCompany') + set::items($companys) ), input ( set::name('company'), setClass('hidden') ), - checkbox + span ( - set::name('new'), - set::rootClass('w-20 justify-end items-center'), - set::value(0), - on::change('onChangeNewCompany'), - set::text($lang->stakeholder->add) + setClass('input-group-addon'), + checkbox + ( + set::name('new'), + set::text($lang->stakeholder->add) + ) ) ) )), From ffd07d6613127538fbe3001fce6ba9b648819057 Mon Sep 17 00:00:00 2001 From: sunhao Date: Thu, 16 Nov 2023 13:50:40 +0800 Subject: [PATCH 027/235] * task: fix link color not effective in table col with styleMap setting. --- module/task/config/dtable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/task/config/dtable.php b/module/task/config/dtable.php index 518e7536bc..26b6519e73 100644 --- a/module/task/config/dtable.php +++ b/module/task/config/dtable.php @@ -12,9 +12,9 @@ $config->task->dtable->fieldList['name']['flex'] = 1; $config->task->dtable->fieldList['name']['type'] = 'nestedTitle'; $config->task->dtable->fieldList['name']['nestedToggle'] = true; $config->task->dtable->fieldList['name']['sortType'] = true; -$config->task->dtable->fieldList['name']['link'] = array('url' => array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}'), 'className' => 'text-inherit'); +$config->task->dtable->fieldList['name']['link'] = array('url' => array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}'), 'className' => 'text-inherit', 'style' => array('color' => 'var(--color-link)')); $config->task->dtable->fieldList['name']['required'] = true; -$config->task->dtable->fieldList['name']['styleMap'] = array('color' => 'color'); +$config->task->dtable->fieldList['name']['styleMap'] = array('--color-link' => 'color'); $config->task->dtable->fieldList['pri']['title'] = $lang->priAB; $config->task->dtable->fieldList['pri']['type'] = 'pri'; From bdec5e82616fc9b4bb214fb4a9aa30b1745e1806 Mon Sep 17 00:00:00 2001 From: songchenxuan Date: Thu, 16 Nov 2023 12:22:44 +0800 Subject: [PATCH 028/235] * Merge commit 3a0d2f9d09, fix bug #40571. --- module/metric/calc/project/hour/ac_of_all_in_waterfall.php | 2 +- .../calc/project/hour/ev_of_finished_task_in_waterfall.php | 2 +- module/metric/calc/project/hour/pv_of_task_in_waterfall.php | 2 +- module/metric/calc/project/rate/cv_in_waterfall.php | 2 +- module/metric/calc/project/rate/sv_in_waterfall.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/module/metric/calc/project/hour/ac_of_all_in_waterfall.php b/module/metric/calc/project/hour/ac_of_all_in_waterfall.php index dd5a79d78b..b2e894cf6a 100755 --- a/module/metric/calc/project/hour/ac_of_all_in_waterfall.php +++ b/module/metric/calc/project/hour/ac_of_all_in_waterfall.php @@ -30,7 +30,7 @@ class ac_of_all_in_waterfall extends baseCalc ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') ->where('t3.deleted')->eq('0') ->andWhere('t3.type')->eq('project') - ->andWhere('t3.model')->eq('waterfall') + ->andWhere('t3.model')->in('waterfall,waterfallplus') ->andWhere("NOT FIND_IN_SET('or', t3.vision)") ->andWhere("NOT FIND_IN_SET('lite', t3.vision)") ->groupBy('t3.id') diff --git a/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php b/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php index 2a24b98bc1..0f7cab44fa 100755 --- a/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php +++ b/module/metric/calc/project/hour/ev_of_finished_task_in_waterfall.php @@ -41,7 +41,7 @@ class ev_of_finished_task_in_waterfall extends baseCalc ->leftJoin("($ev)")->alias('t2')->on('t1.id=t2.project') ->where('t1.deleted')->eq('0') ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->eq('waterfall') + ->andWhere('t1.model')->in('waterfall,waterfallplus') ->andWhere("NOT FIND_IN_SET('or', t1.vision)") ->andWhere("NOT FIND_IN_SET('lite', t1.vision)") ->query(); diff --git a/module/metric/calc/project/hour/pv_of_task_in_waterfall.php b/module/metric/calc/project/hour/pv_of_task_in_waterfall.php index 4095bb16a9..c2563c45fb 100755 --- a/module/metric/calc/project/hour/pv_of_task_in_waterfall.php +++ b/module/metric/calc/project/hour/pv_of_task_in_waterfall.php @@ -41,7 +41,7 @@ class pv_of_task_in_waterfall extends baseCalc ->leftJoin("($pv)")->alias('t2')->on('t1.id=t2.project') ->where('t1.deleted')->eq('0') ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->eq('waterfall') + ->andWhere('t1.model')->in('waterfall,waterfallplus') ->andWhere("NOT FIND_IN_SET('or', t1.vision)") ->andWhere("NOT FIND_IN_SET('lite', t1.vision)") ->query(); diff --git a/module/metric/calc/project/rate/cv_in_waterfall.php b/module/metric/calc/project/rate/cv_in_waterfall.php index 5008a521b3..974acb7154 100755 --- a/module/metric/calc/project/rate/cv_in_waterfall.php +++ b/module/metric/calc/project/rate/cv_in_waterfall.php @@ -51,7 +51,7 @@ class cv_in_waterfall extends baseCalc ->leftJoin("($ac)")->alias('t3')->on('t1.id=t3.project') ->where('t1.deleted')->eq('0') ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->eq('waterfall') + ->andWhere('t1.model')->in('waterfall,waterfallplus') ->query(); } diff --git a/module/metric/calc/project/rate/sv_in_waterfall.php b/module/metric/calc/project/rate/sv_in_waterfall.php index f888e79337..6e084ca7e6 100755 --- a/module/metric/calc/project/rate/sv_in_waterfall.php +++ b/module/metric/calc/project/rate/sv_in_waterfall.php @@ -41,7 +41,7 @@ class sv_in_waterfall extends baseCalc ->leftJoin("($task)")->alias('t2')->on('t1.id=t2.project') ->where('t1.deleted')->eq('0') ->andWhere('t1.type')->eq('project') - ->andWhere('t1.model')->eq('waterfall') + ->andWhere('t1.model')->in('waterfall,waterfallplus') ->andWhere("NOT FIND_IN_SET('or', t1.vision)") ->andWhere("NOT FIND_IN_SET('lite', t1.vision)") ->query(); From 55fabb1873b486d4a214b13fe0bcca7e01372796 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 16 Nov 2023 13:53:19 +0800 Subject: [PATCH 029/235] * Adjust file download for repo. --- module/repo/js/ajaxgeteditorcontent.ui.js | 6 ++++++ module/repo/js/diff.ui.js | 2 +- module/repo/js/monaco.ui.js | 2 +- module/repo/ui/ajaxgeteditorcontent.html.php | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/module/repo/js/ajaxgeteditorcontent.ui.js b/module/repo/js/ajaxgeteditorcontent.ui.js index feed9b12f1..e6b5054ea0 100644 --- a/module/repo/js/ajaxgeteditorcontent.ui.js +++ b/module/repo/js/ajaxgeteditorcontent.ui.js @@ -236,3 +236,9 @@ function initPage() /* Get file commits. */ showCommitInfo(); } + +window.downloadCode = function() +{ + var url = $(this).data('link'); + window.open(url, '_self'); +} diff --git a/module/repo/js/diff.ui.js b/module/repo/js/diff.ui.js index ea38b0de03..bacdb23f5d 100644 --- a/module/repo/js/diff.ui.js +++ b/module/repo/js/diff.ui.js @@ -52,7 +52,7 @@ window.downloadCode = function() { var url = $(this).data('link'); var activeFilePath = $('#monacoTabs .nav-item .active').attr('href').substring(5).replace(/-/g, '='); - window.open(url.replace('{path}', activeFilePath)); + window.open(url.replace('{path}', activeFilePath), '_self'); return; } diff --git a/module/repo/js/monaco.ui.js b/module/repo/js/monaco.ui.js index d391b1c6f3..5688e77ffe 100644 --- a/module/repo/js/monaco.ui.js +++ b/module/repo/js/monaco.ui.js @@ -70,7 +70,7 @@ window.afterPageUpdate = function() } else { - window.open(url.replace('{path}', activeFilePath)); + window.open(url.replace('{path}', activeFilePath), '_self'); } return; }) diff --git a/module/repo/ui/ajaxgeteditorcontent.html.php b/module/repo/ui/ajaxgeteditorcontent.html.php index 40a809abd1..ff7591a729 100644 --- a/module/repo/ui/ajaxgeteditorcontent.html.php +++ b/module/repo/ui/ajaxgeteditorcontent.html.php @@ -57,9 +57,9 @@ elseif($suffix == 'binary') set::className('binary'), a ( - set::href($this->repo->createLink('download', "repoID=$repoID&path=" . $this->repo->encodePath($entry) . "&fromRevision=$revision")), + set('data-link', $this->repo->createLink('download', "repoID=$repoID&path=" . $this->repo->encodePath($entry) . "&fromRevision=$revision")), icon('download'), - set::target('_blank'), + on::click('downloadCode'), set::title($this->lang->repo->download) ) ); From 67142f60301dea3473e32814849d7ef75e3681a3 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 16 Nov 2023 13:57:20 +0800 Subject: [PATCH 030/235] * Adjust file download for mr. --- module/mr/ui/diff.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/mr/ui/diff.html.php b/module/mr/ui/diff.html.php index 87dc29b485..c0174f9fdb 100644 --- a/module/mr/ui/diff.html.php +++ b/module/mr/ui/diff.html.php @@ -52,7 +52,7 @@ jsVar('diffLink', $diffLink); jsVar('urlParams', "repoID=$repoID&objectID=$objectID&entry=%s&oldRevision=$oldRevision&newRevision=$newRevision&showBug=$showBug&encoding=$encoding"); $dropMenus = array(); -if(common::hasPriv('repo', 'download')) $dropMenus[] = array('text' => $this->lang->repo->downloadDiff, 'icon' => 'download', 'url' => $this->repo->createLink('download', "repoID=$repoID&path=$currentEntry&fromRevision=$oldRevision&toRevision=$newRevision&type=path"), 'target' => '_blank'); +if(common::hasPriv('repo', 'download')) $dropMenus[] = array('text' => $this->lang->repo->downloadDiff, 'icon' => 'download', 'url' => $this->repo->createLink('download', "repoID=$repoID&path=$currentEntry&fromRevision=$oldRevision&toRevision=$newRevision&type=path"), 'target' => '_self'); $dropMenus[] = array('text' => $this->lang->repo->viewDiffList['inline'], 'icon' => 'snap-house', 'id' => 'inline', 'class' => 'inline-appose'); $dropMenus[] = array('text' => $this->lang->repo->viewDiffList['appose'], 'icon' => 'col-archive', 'id' => 'appose', 'class' => 'inline-appose'); From 34788f460461a0a668ce6056d0be4bfd2303b86d Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 14:05:02 +0800 Subject: [PATCH 031/235] * Rendering the title's color of product browse page. --- module/product/js/browse.ui.js | 1 - module/story/config/dtable.php | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/product/js/browse.ui.js b/module/product/js/browse.ui.js index 32a8f8613f..943bb459dc 100644 --- a/module/product/js/browse.ui.js +++ b/module/product/js/browse.ui.js @@ -50,7 +50,6 @@ window.renderCell = function(result, info) if(info.col.name == 'title' && result) { const story = info.row.data; - if(story.color) result[0].props.style = 'color: ' + story.color; let html = ''; if(showBranch) html += "" + story.branch + " "; if(typeof modulePairs[story.rawModule] != 'undefined') html += "" + modulePairs[story.rawModule] + " "; diff --git a/module/story/config/dtable.php b/module/story/config/dtable.php index 0b91061631..25b202d98a 100644 --- a/module/story/config/dtable.php +++ b/module/story/config/dtable.php @@ -26,7 +26,7 @@ if($app->tab == 'execution') $config->story->dtable->fieldList['title']['name'] = 'title'; $config->story->dtable->fieldList['title']['title'] = $lang->story->title; $config->story->dtable->fieldList['title']['type'] = 'title'; -$config->story->dtable->fieldList['title']['link'] = helper::createLink('story', 'view', 'storyID={id}'); +$config->story->dtable->fieldList['title']['link'] = array('url' => helper::createLink('story', 'view', 'storyID={id}'), 'style' => array('color' => 'var(--color-link)')); $config->story->dtable->fieldList['title']['fixed'] = 'left'; $config->story->dtable->fieldList['title']['sortType'] = true; $config->story->dtable->fieldList['title']['minWidth'] = '342'; @@ -35,6 +35,7 @@ $config->story->dtable->fieldList['title']['nestedToggle'] = true; $config->story->dtable->fieldList['title']['show'] = true; $config->story->dtable->fieldList['title']['group'] = 1; $config->story->dtable->fieldList['title']['data-app'] = $app->tab; +$config->story->dtable->fieldList['title']['styleMap'] = array('--color-link' => 'color'); $config->story->dtable->fieldList['pri']['name'] = 'pri'; $config->story->dtable->fieldList['pri']['title'] = $lang->priAB; From 391b229760472c0b8ccb82057f862bb8669814bb Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 14:11:27 +0800 Subject: [PATCH 032/235] * Change to new writing method. --- module/block/ui/edit.html.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/block/ui/edit.html.php b/module/block/ui/edit.html.php index 11cd58123e..66459d8c42 100644 --- a/module/block/ui/edit.html.php +++ b/module/block/ui/edit.html.php @@ -31,7 +31,7 @@ row $showModules ? cell ( set::width(128), - set::className('flex-none bg-surface rounded rounded-r-none rounded-tl-none overflow-y-auto'), + setClass('flex-none bg-surface rounded rounded-r-none rounded-tl-none overflow-y-auto'), buildBlockModuleNav() ) : null, cell @@ -53,7 +53,7 @@ row ), formRow ( - set::id('codesRow'), + setID('codesRow'), setClass($showCodes ? '' : 'hidden'), formGroup ( @@ -72,8 +72,8 @@ row ), div ( - set::id('paramsRow'), - set::className('space-y-4'), + setID('paramsRow'), + setClass('space-y-4'), formRow ( formGroup @@ -102,7 +102,7 @@ row ), formRow ( - set::className($module == 'html' ? '' : 'hidden'), + setClass($module == 'html' ? '' : 'hidden'), formGroup ( set::label($lang->block->lblHtml), From 021a58f3195a48e6cadb78f894cd7f0872d2a6d4 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 14:14:02 +0800 Subject: [PATCH 033/235] * Change to new writing method. --- module/block/ui/caseblock.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/block/ui/caseblock.html.php b/module/block/ui/caseblock.html.php index 16f5eb60d9..f7bd10481a 100644 --- a/module/block/ui/caseblock.html.php +++ b/module/block/ui/caseblock.html.php @@ -25,7 +25,7 @@ blockPanel setClass('case-block list-block'), dtable ( - set::id('case'), + setID('case'), set::height(320), set::bordered(false), set::horzScrollbarPos('inside'), From b15935c1b56247ee9d44501ea15b5a3001b0ffa1 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:16:05 +0800 Subject: [PATCH 034/235] * project: merge code to bind same function to different controls. --- module/project/ui/create.html.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index d8381cd503..73d4609d95 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -158,8 +158,7 @@ formPanel on::change('[name^=branch]', 'branchChange'), on::change('#parent', 'setParentProgram'), on::change('[name=multiple]', 'toggleMultiple'), - on::change('#begin', 'computeWorkDays'), - on::change('#end', 'computeWorkDays'), + on::change('#begin, #end', 'computeWorkDays'), on::change('[name=delta]', 'setDate'), on::change('[name=future]', 'toggleBudget'), on::change('[name=newProduct]', 'addProduct'), From 78f5b5a1d30108c69deb85ed5feeb54ab13c0424 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:17:49 +0800 Subject: [PATCH 035/235] * project: sort code to bind javascript functions to html tags. --- module/project/ui/create.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 73d4609d95..1ac2245e07 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -154,11 +154,11 @@ formPanel on::click('[type=submit]', 'removeAllTips'), on::click('#name, #code, #end, #days', 'removeTips'), on::change('#end, #days', 'removeTips'), + on::change('#begin, #end', 'computeWorkDays'), + on::change('#parent', 'setParentProgram'), on::change('[name^=products]', 'productChange'), on::change('[name^=branch]', 'branchChange'), - on::change('#parent', 'setParentProgram'), on::change('[name=multiple]', 'toggleMultiple'), - on::change('#begin, #end', 'computeWorkDays'), on::change('[name=delta]', 'setDate'), on::change('[name=future]', 'toggleBudget'), on::change('[name=newProduct]', 'addProduct'), From ce53f56871bd6c4a74e0dacc6f25f74c007ac438 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:21:41 +0800 Subject: [PATCH 036/235] * project: replace set('id', xxx) with setID(xxx). --- module/project/ui/create.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 1ac2245e07..4c38cfdb65 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -302,16 +302,16 @@ formPanel ( datepicker ( + setID('begin'), set::name('begin'), - set('id', 'begin'), set::value(date('Y-m-d')), set::required(true) ), $lang->project->to, datepicker ( + setID('end'), set::name('end'), - set('id', 'end'), set::placeholder($lang->project->end), set::required(true), $copyProjectID ? setClass('has-warning') : null From c08c976a65febd5db16d771becf7c49060a13a5b Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:23:19 +0800 Subject: [PATCH 037/235] + project: add a hidden inputControl to display the end date of long time project. --- module/project/ui/create.html.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 4c38cfdb65..5b7e880a49 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -315,6 +315,16 @@ formPanel set::placeholder($lang->project->end), set::required(true), $copyProjectID ? setClass('has-warning') : null + ), + inputControl + ( + setClass('has-suffix-icon w-full hidden'), + to::suffix(icon('calendar')), + input + ( + set::value($lang->project->longTime), + set::disabled(true) + ) ) ), $copyProjectID ? div(setClass('text-warning'), $lang->project->copyProject->endTips) : null From 59f388a0f587f40940c1b9cfdc7850bae729767b Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:25:30 +0800 Subject: [PATCH 038/235] * project: bind the setDate() function to the begin control. --- module/project/ui/create.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 5b7e880a49..65ffa8f9d4 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -159,7 +159,7 @@ formPanel on::change('[name^=products]', 'productChange'), on::change('[name^=branch]', 'branchChange'), on::change('[name=multiple]', 'toggleMultiple'), - on::change('[name=delta]', 'setDate'), + on::change('#begin, [name=delta]', 'setDate'), on::change('[name=future]', 'toggleBudget'), on::change('[name=newProduct]', 'addProduct'), formRow From a97817a0d8cfc63b53bb5585c7e4828f7d12abfe Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 14:25:41 +0800 Subject: [PATCH 039/235] * Change to new writing method. --- module/block/ui/create.html.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/block/ui/create.html.php b/module/block/ui/create.html.php index 3bd6a2cd17..2014599dc6 100644 --- a/module/block/ui/create.html.php +++ b/module/block/ui/create.html.php @@ -28,11 +28,11 @@ foreach(array_keys($blockSize) as $width) $widthOptions[$width] = zget($this->la $defaultWidth = reset($widthOptions); row ( - set::id('blockCreateForm'), + setID('blockCreateForm'), $showModules ? cell ( set::width(128), - set::className('flex-none bg-surface rounded rounded-r-none rounded-tl-none overflow-y-auto'), + setClass('flex-none bg-surface rounded rounded-r-none rounded-tl-none overflow-y-auto'), buildBlockModuleNav() ) : null, cell @@ -53,7 +53,7 @@ row ), formRow ( - set::id('codesRow'), + setID('codesRow'), setClass($showCodes ? '' : 'hidden'), formGroup ( @@ -73,8 +73,8 @@ row ), div ( - set::id('paramsRow'), - set::className('space-y-4'), + setID('paramsRow'), + setClass('space-y-4'), formRow ( formGroup From 7e15d9a0be19d05921a513cecdd8930a32fcf26d Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 16 Nov 2023 14:29:14 +0800 Subject: [PATCH 040/235] * Fix the bug of search cases in testtask. --- module/testtask/ui/linkcase.html.php | 2 +- module/testtask/zen.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/testtask/ui/linkcase.html.php b/module/testtask/ui/linkcase.html.php index b527187e70..0e734e738b 100644 --- a/module/testtask/ui/linkcase.html.php +++ b/module/testtask/ui/linkcase.html.php @@ -68,7 +68,7 @@ featureBar set::current($type), set::linkParams("taskID={$task->id}&type={key}"), to::before(backBtn(set::icon('back'), set::className('btn secondary'), $lang->goback)), - li(searchToggle(set::module('testcase'), set::open($type == 'bySearch'))) + li(searchToggle(set::module('testcase'), set::open(true))) ); $footToolbar = array('items' => array diff --git a/module/testtask/zen.php b/module/testtask/zen.php index 567d3e99d4..460c56df64 100644 --- a/module/testtask/zen.php +++ b/module/testtask/zen.php @@ -81,7 +81,7 @@ class testtaskZen extends testtask $searchConfig = $this->config->testcase->search; $searchConfig['style'] = 'simple'; - $searchConfig['actionURL'] = inlink('linkcase', "taskID={$task->id}&type=bySearch¶m={$param}"); + $searchConfig['actionURL'] = inlink('linkcase', "taskID={$task->id}&type={$type}¶m={$param}"); $searchConfig['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($product->id, 'case', 0, $task->branch); $searchConfig['params']['scene']['values'] = $this->testcase->getSceneMenu($product->id); $searchConfig['params']['product']['values'] = array($product->id => $product->name); From 68ae1f1b6a91991323bc9d4ce44c7557f6b4e539 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:32:58 +0800 Subject: [PATCH 041/235] * project: refactor the javascript computeEndDate() function. --- module/project/js/common.ui.js | 31 ++++++++----------------------- module/project/ui/create.html.php | 1 + 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 97f4da6da8..1e532404a1 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -141,36 +141,21 @@ function computeWorkDays(e) * 计算并设置计划完成时间。 * Compute the end date for project. * - * @param int delta * @access public * @return void */ -function computeEndDate(delta) +function computeEndDate() { - let beginDate = $('#begin').zui('datePicker').$.state.value; + const beginDate = $('#begin').zui('datePicker').$.state.value; if(!beginDate) return; - delta = parseInt(delta); - if(delta == 999) - { - $('#end').datePicker({disabled: true}); - $('#days').val(0).closest('.form-row').addClass('hidden'); - outOfDateTip(); - return false; - } + const delta = parseInt($('input[name=delta]:checked').val()); + const isLongTime = delta == 999; + const endDate = isLongTime ? LONG_TIME : formatDate(beginDate, delta - 1); - $('#end').datePicker({disabled: false}); - $('#days').closest('.form-row').removeClass('hidden'); - - beginDate = convertStringToDate(beginDate); - if((delta == 7 || delta == 14) && (beginDate.getDay() == 1)) - { - delta = (weekend == 2) ? (delta - 2) : (delta - 1); - } - - endDate = formatDate(beginDate, delta - 1); - $('#end').zui('datePicker').$.changeState({value: endDate}); - computeWorkDays(); + $('#end').toggleClass('hidden', isLongTime).zui('datePicker').$.changeState({value: endDate}); + $('#end').next().toggleClass('hidden', !isLongTime); + $('#days').closest('.form-row').toggleClass('hidden', isLongTime); } /** diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 65ffa8f9d4..89d2e67b30 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -2,6 +2,7 @@ namespace zin; jsVar('model', $model); +jsVar('LONG_TIME', LONG_TIME); jsVar('longTime', $lang->project->longTime); jsVar('weekend', $config->execution->weekend); jsVar('beginLessThanParent', $lang->project->beginLessThanParent); From 7cd69825f6a9671348645c7c44c1fd3ab0e55b82 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:35:52 +0800 Subject: [PATCH 042/235] * project: simplify the javascript formatDate() function. --- module/project/js/common.ui.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 1e532404a1..0e97f55cc8 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -160,22 +160,19 @@ function computeEndDate() /** * 给指定日期加上具体天数,并返回格式化后的日期. + * Add days to date, and return formatted date. * * @param string dateString * @param int days * @access public - * @return date + * @return string */ function formatDate(dateString, days) { - const date = new Date(dateString); - date.setDate(date.getDate() + days); + const date = new Date(dateString); + date.setDate(date.getDate() + days); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - - return `${year}-${month}-${day}`; + return date.toLocaleDateString('en-CA') } /** From 1a2f17adb1d47dc9ce3130a9c98f30ca2279e8b8 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:39:47 +0800 Subject: [PATCH 043/235] * project: add a const of milliseconds of a day. --- module/project/js/common.ui.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 0e97f55cc8..37a2f887ac 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -1,3 +1,5 @@ +const DAY_MILLISECONDS = 24 * 60 * 60 * 1000; + window.ignoreTips = { 'beyondBudgetTip' : false, 'dateTip' : false @@ -72,7 +74,7 @@ function computeDaysDelta(date1, date2) { date1 = convertStringToDate(date1); date2 = convertStringToDate(date2); - delta = (date2 - date1) / (1000 * 60 * 60 * 24) + 1; + delta = (date2 - date1) / DAY_MILLISECONDS + 1; if(isNaN(delta)) return; @@ -81,7 +83,7 @@ function computeDaysDelta(date1, date2) { if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekEnds ++; date1 = date1.valueOf(); - date1 += 1000 * 60 * 60 * 24; + date1 += DAY_MILLISECONDS; date1 = new Date(date1); } return delta - weekEnds; @@ -120,7 +122,7 @@ function computeWorkDays(e) var begin = new Date(beginDate.replace(/-/g,"/")); var end = new Date(endDate.replace(/-/g,"/")); var time = end.getTime() - begin.getTime(); - var days = parseInt(time / (1000 * 60 * 60 * 24)) + 1; + var days = parseInt(time / DAY_MILLISECONDS) + 1; if(days != $("input[name='delta']:checked").val()) $("input[name='delta']:checked").attr('checked', false); if(endDate == longTime) $("#delta999").prop('checked', true); } From 13f7ade33b83cb06899dcba3d05292a5f90efbe3 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:41:17 +0800 Subject: [PATCH 044/235] * project: refactor the javascript function to compute work days between two dates. --- module/project/js/common.ui.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 37a2f887ac..20620c2170 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -62,8 +62,8 @@ function setDate() } /** - * 计算两个时间的天数。 - * Compute delta of two days. + * 计算两个日期之间可用的工作日。 + * Compute work days between two dates. * * @param string date1 * @param string date2 @@ -72,21 +72,20 @@ function setDate() */ function computeDaysDelta(date1, date2) { - date1 = convertStringToDate(date1); - date2 = convertStringToDate(date2); - delta = (date2 - date1) / DAY_MILLISECONDS + 1; + date1 = new Date(date1); + date2 = new Date(date2); + const time = date2 - date1; + const days = parseInt(time / DAY_MILLISECONDS) + 1; + if(isNaN(days)) return; - if(isNaN(delta)) return; - - weekEnds = 0; - for(i = 0; i < delta; i++) + let weekendDays = 0; + for(i = 0; i < days; i++) { - if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekEnds ++; - date1 = date1.valueOf(); - date1 += DAY_MILLISECONDS; + if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekendDays ++; + date1 = date1.valueOf() + DAY_MILLISECONDS; date1 = new Date(date1); } - return delta - weekEnds; + return days - weekendDays; } /** From 0632815cfa0b51a05b922fa46331833efc0c78cd Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:42:59 +0800 Subject: [PATCH 045/235] * project: refactor the javascript function to update work days. --- module/project/js/common.ui.js | 52 +++++++++++----------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 20620c2170..c9f7e903fe 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -89,53 +89,35 @@ function computeDaysDelta(date1, date2) } /** - * 计算可用工作日天数。 - * Compute work days. + * 更新可用工作日天数。 + * Update work days. * - * @param string currentID * @access public * @return void */ -function computeWorkDays(e) +function computeWorkDays() { - isBactchEdit = false; - let currentID = typeof e == 'object' ? $(e.target).attr('id') : ''; - if(currentID) - { - index = currentID.replace('begins[', ''); - index = index.replace('ends[', ''); - index = index.replace(']', ''); - if(!isNaN(index)) isBactchEdit = true; - } + const begin = $('#begin').zui('datePicker').$.state.value; + const end = $('#end').zui('datePicker').$.state.value; - if(isBactchEdit) + if(end == LONG_TIME) { - beginDate = $('#begins\\[' + index + '\\]').zui('datePicker').$.state.value; - endDate = $('#ends\\[' + index + '\\]').zui('datePicker').$.state.value; + $('#delta999').prop('checked', true); + $('#days').val(0).tigger('change'); } else { - beginDate = $('#begin').zui('datePicker').$.state.value; - endDate = $('#end').zui('datePicker').$.state.value; - - var begin = new Date(beginDate.replace(/-/g,"/")); - var end = new Date(endDate.replace(/-/g,"/")); - var time = end.getTime() - begin.getTime(); - var days = parseInt(time / DAY_MILLISECONDS) + 1; - if(days != $("input[name='delta']:checked").val()) $("input[name='delta']:checked").attr('checked', false); - if(endDate == longTime) $("#delta999").prop('checked', true); + $('#days').val(computeDaysDelta(begin, end)).trigger('change'); + const time = new Date(end) - new Date(begin); + const days = parseInt(time / DAY_MILLISECONDS) + 1; + if(days != $("input[name='delta']:checked").val()) + { + $("input[name='delta']:checked").prop('checked', false); + $('#delta' + days).prop('checked', true); + } } - if(beginDate && endDate) - { - if(isBactchEdit) $('#dayses\\[' + index + '\\]').val(computeDaysDelta(beginDate, endDate)); - if(!isBactchEdit) $('#days').val(computeDaysDelta(beginDate, endDate)).trigger('change'); - } - else if($('input[checked="true"]').val()) - { - computeEndDate(); - } - outOfDateTip(isBactchEdit ? index : 0); + outOfDateTip(); } /** From a5a70873f457d1e9682b4694ad0afb8968afe30b Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:45:07 +0800 Subject: [PATCH 046/235] * project: bind the javascript computeEndDate() function to change event of html tags. --- module/project/ui/create.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 89d2e67b30..390f83f0da 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -155,12 +155,12 @@ formPanel on::click('[type=submit]', 'removeAllTips'), on::click('#name, #code, #end, #days', 'removeTips'), on::change('#end, #days', 'removeTips'), - on::change('#begin, #end', 'computeWorkDays'), on::change('#parent', 'setParentProgram'), + on::change('#begin, [name=delta]', 'computeEndDate'), + on::change('#begin, #end', 'computeWorkDays'), on::change('[name^=products]', 'productChange'), on::change('[name^=branch]', 'branchChange'), on::change('[name=multiple]', 'toggleMultiple'), - on::change('#begin, [name=delta]', 'setDate'), on::change('[name=future]', 'toggleBudget'), on::change('[name=newProduct]', 'addProduct'), formRow From 46b764ad9b88e830e0e3a391e30163d28681a1d6 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 14:47:56 +0800 Subject: [PATCH 047/235] - project: remove unused javascript function. --- module/project/js/common.ui.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index c9f7e903fe..7e03fb32fa 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -48,19 +48,6 @@ function changeStageBy(type) $('input[name=stageBy]').val(type); } -/** - * 设置计划结束时间。 - * Set plan end date. - * - * @access public - * @return void - */ -function setDate() -{ - const delta = $('input[name=delta]:checked').val(); - computeEndDate(delta); -} - /** * 计算两个日期之间可用的工作日。 * Compute work days between two dates. From 91351cb51da9247e927098f54fe18996fde6f623 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 14:57:47 +0800 Subject: [PATCH 048/235] - Remove search form in project::execution. --- module/project/ui/execution.html.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/project/ui/execution.html.php b/module/project/ui/execution.html.php index a185a27a51..d989ef02e6 100644 --- a/module/project/ui/execution.html.php +++ b/module/project/ui/execution.html.php @@ -81,7 +81,6 @@ featureBar ), set::current($status), set::linkParams("status={key}&projectID={$projectID}&orderBy={$orderBy}&productID={$productID}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"), - li(searchToggle()), li ( checkbox From 4b20b888f9134de41e5952d5c7d9e3a097037c95 Mon Sep 17 00:00:00 2001 From: sunhao Date: Thu, 16 Nov 2023 14:35:44 +0800 Subject: [PATCH 049/235] - zin: delete unused files. --- lib/zin/wg/searchtoggle/css/v1.css | 3 --- lib/zin/wg/searchtoggle/js/v1.js | 29 ----------------------------- 2 files changed, 32 deletions(-) delete mode 100644 lib/zin/wg/searchtoggle/css/v1.css delete mode 100644 lib/zin/wg/searchtoggle/js/v1.js diff --git a/lib/zin/wg/searchtoggle/css/v1.css b/lib/zin/wg/searchtoggle/css/v1.css deleted file mode 100644 index 7ff2b5bcc0..0000000000 --- a/lib/zin/wg/searchtoggle/css/v1.css +++ /dev/null @@ -1,3 +0,0 @@ -.show-search-form #featureBar .search-form-toggle {color: var(--color-primary-500); background-color: var(--color-primary-50);} -#searchFormPanel {display: none;} -.show-search-form #searchFormPanel {display: block; margin-bottom: 12px;} diff --git a/lib/zin/wg/searchtoggle/js/v1.js b/lib/zin/wg/searchtoggle/js/v1.js deleted file mode 100644 index 5f2e241827..0000000000 --- a/lib/zin/wg/searchtoggle/js/v1.js +++ /dev/null @@ -1,29 +0,0 @@ -window.toggleSearchForm = function(moduleName, formName, open, trigger) -{ - typeof open == 'undefined' ? $('body').toggleClass('show-search-form') : $('body').toggleClass('show-search-form', open); - - const $body = $('body'); - const show = $body.hasClass('show-search-form'); - if(!show) return; - - const isCustomFormName = (typeof formName != 'undefined' && formName != ''); - if(typeof moduleName == 'undefined' || moduleName == '') moduleName = config.currentModule; - - let $form = $body.find('#searchFormPanel[data-module="' + moduleName + '"]'); - if(isCustomFormName) $form = $body.find('#' + formName); - if(!$form.length) - { - $form = $('
'); - let $mainCell = $body.find('.main-content-cell'); - if(!$mainCell.length) $mainCell = $body.find('#mainContent'); - if($mainCell.length) $mainCell.prepend($form); - } - if(!$form.data('loaded')) - { - const url = $.createLink('search', config.zin === 'compatible' ? 'buildZinForm' : 'buildForm', 'module=' + moduleName + '&fields=¶ms=&actionURL=&queryID=0&formName=' + formName); - $.get(url, html => - { - $form.html(html).data('loaded', true); - }); - } -}; From a647a805861e82e7ec4d79c21971b504f735702b Mon Sep 17 00:00:00 2001 From: sunhao Date: Thu, 16 Nov 2023 14:36:13 +0800 Subject: [PATCH 050/235] * zin/input: unset empty id property. --- lib/zin/wg/input/v1.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/zin/wg/input/v1.php b/lib/zin/wg/input/v1.php index 0b4731583f..1d1fc6f40b 100644 --- a/lib/zin/wg/input/v1.php +++ b/lib/zin/wg/input/v1.php @@ -27,6 +27,7 @@ class input extends wg $props = $this->props->skip('required'); $required = $this->prop('required'); if(!$this->hasProp('id') && isset($props['name'])) $props['id'] = $props['name']; + if(empty($props['id'])) unset($props['id']); if(is_bool($props['autocomplete'])) $props['autocomplete'] = $props['autocomplete'] ? 'on' : 'off'; return h::input(set($props), $required ? setClass('is-required') : null); } From 7adc68f1a459908eec59ef78293d845a68ff4962 Mon Sep 17 00:00:00 2001 From: sunhao Date: Thu, 16 Nov 2023 15:02:22 +0800 Subject: [PATCH 051/235] * zin/editor: refactor. --- lib/zin/wg/editor/v1.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/zin/wg/editor/v1.php b/lib/zin/wg/editor/v1.php index a00424118f..625517557a 100644 --- a/lib/zin/wg/editor/v1.php +++ b/lib/zin/wg/editor/v1.php @@ -18,7 +18,7 @@ class editor extends wg 'bubbleMenu?: bool=false', // 是否启用菜单冒泡 'menubarMode?: string="compact"', // 菜单栏模式 'value?: string', // 内容 - 'uid?: string=""' // 图片上传uid + 'uid?: string' // 图片上传uid ); public static function getPageCSS(): string|false @@ -36,8 +36,7 @@ class editor extends wg protected function created() { - $uid = $this->prop('uid'); - if(!$uid) $this->setProp('uid', uniqid()); + if(empty($this->prop('uid'))) $this->setProp('uid', $this->gid); $this->setDefaultProps(array('uploadUrl' => helper::createLink('file', 'ajaxUpload', 'uid=' . $this->prop('uid')))); } @@ -66,7 +65,7 @@ class editor extends wg return div ( - setClass('editor-container p-px'), + setClass('editor-container p-px mt-px rounded ring -ring-offset-1'), $props['size'] === 'full' ? setStyle('height', '100%') : setClass('h-auto'), $editor, textarea From 86c45f069c008b852b283068615ffb5cce30d061 Mon Sep 17 00:00:00 2001 From: sunhao Date: Thu, 16 Nov 2023 15:04:48 +0800 Subject: [PATCH 052/235] * action: fix action/comment conflict with other form. --- module/action/config/form.php | 2 +- module/action/control.php | 2 +- module/action/ui/comment.html.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/action/config/form.php b/module/action/config/form.php index ad086c9f17..3d31ecefde 100644 --- a/module/action/config/form.php +++ b/module/action/config/form.php @@ -1,7 +1,7 @@ action->form = new stdclass(); $config->action->form->comment = array(); -$config->action->form->comment['comment'] = array('type' => 'string', 'required' => true, 'default' => '', 'control' => 'editor'); +$config->action->form->comment['actioncomment'] = array('type' => 'string', 'required' => true, 'default' => '', 'control' => 'editor'); $config->action->form->editComment = array(); $config->action->form->editComment['lastComment'] = array('type' => 'string', 'required' => true, 'default' => '', 'control' => 'editor'); diff --git a/module/action/control.php b/module/action/control.php index 53fb3cdc30..cb5cb91b5a 100755 --- a/module/action/control.php +++ b/module/action/control.php @@ -251,7 +251,7 @@ class action extends control /* 获取评论内容并生成一条action数据。 */ $commentData = form::data($this->config->action->form->comment)->get(); - $actionID = $this->action->create($objectType, $objectID, 'Commented', $commentData->comment); + $actionID = $this->action->create($objectType, $objectID, 'Commented', $commentData->actioncomment); if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success', 'data' => $actionID)); /* 用于ZIN的新UI。*/ diff --git a/module/action/ui/comment.html.php b/module/action/ui/comment.html.php index 6bdf3f3b5e..60438cc621 100644 --- a/module/action/ui/comment.html.php +++ b/module/action/ui/comment.html.php @@ -22,7 +22,7 @@ form setClass('comment-form'), editor ( - set::name('comment') + set::name('actioncomment') ), set::actions($actions) ); From c79380d8edc16f09b9214c46e24eedffe705879b Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 15:03:43 +0800 Subject: [PATCH 053/235] * Remove required label when add a new line. --- module/task/js/common.ui.js | 1 + 1 file changed, 1 insertion(+) diff --git a/module/task/js/common.ui.js b/module/task/js/common.ui.js index adda2223f2..6202c60b15 100644 --- a/module/task/js/common.ui.js +++ b/module/task/js/common.ui.js @@ -9,6 +9,7 @@ $('#teamTable').on('click.team', '.btn-add', function() $newRow.find('input').val(''); $newRow.find('[name^=teamConsumed]').val(0); + $newRow.find('.required').removeClass('required'); $(this).closest('tr').after($newRow); toggleBtn(); From b87916cc0f6680f0369f349a9b01d4bde0201692 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 15:05:07 +0800 Subject: [PATCH 054/235] * Adjust warning icon style. --- module/task/css/recordworkhour.ui.css | 2 +- module/task/ui/recordworkhour.html.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/task/css/recordworkhour.ui.css b/module/task/css/recordworkhour.ui.css index aade6abd90..8b9cdb28b5 100644 --- a/module/task/css/recordworkhour.ui.css +++ b/module/task/css/recordworkhour.ui.css @@ -3,4 +3,4 @@ .panel-form .panel-heading {padding: 1.5rem 0} .panel-form .panel-heading .panel-title {font-size: 14px} .panel-form .panel-body {padding: 0 0 1rem 0} -div.alert {margin: 10px 0} +div.alert > .icon {font-size: 42px;} diff --git a/module/task/ui/recordworkhour.html.php b/module/task/ui/recordworkhour.html.php index 3ae536726d..07b95ccb6b 100644 --- a/module/task/ui/recordworkhour.html.php +++ b/module/task/ui/recordworkhour.html.php @@ -151,7 +151,7 @@ if(!$this->task->canOperateEffort($task)) div ( setClass('alert with-icon'), - icon('exclamation-sign'), + icon('exclamation-sign text-gray'), div ( setClass('content'), From 5afd9db95957d2f92ea575e6818c97004db8c0fa Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 15:05:40 +0800 Subject: [PATCH 055/235] * Refactor manage team page and js. --- module/task/css/manageteam.ui.css | 2 + module/task/js/manageteam.ui.js | 45 +++++++++ module/task/ui/edit.html.php | 2 +- module/task/ui/manageteam.html.php | 151 +++++++---------------------- 4 files changed, 85 insertions(+), 115 deletions(-) create mode 100644 module/task/css/manageteam.ui.css create mode 100644 module/task/js/manageteam.ui.js diff --git a/module/task/css/manageteam.ui.css b/module/task/css/manageteam.ui.css new file mode 100644 index 0000000000..7deff58a16 --- /dev/null +++ b/module/task/css/manageteam.ui.css @@ -0,0 +1,2 @@ +div.alert > .icon {font-size: 42px;} +#teamTable.table tr {border: none;} diff --git a/module/task/js/manageteam.ui.js b/module/task/js/manageteam.ui.js new file mode 100644 index 0000000000..f25dbcb2f7 --- /dev/null +++ b/module/task/js/manageteam.ui.js @@ -0,0 +1,45 @@ +window.waitDom('.picker-box [name^=team]', function() +{ + disableMembers(); +}); + +window.clickSubmit = function() +{ + let memberCount = ''; + let error = false; + + $('.picker-box [name^=team]').each(function() + { + if($(this).val() == '') return; + + memberCount++; + + let $tr = $(this).closest('tr'); + let account = $tr.find('.picker-single-selection').text(); + let estimate = parseFloat($tr.find('[name^=teamEstimate]').val()); + + if($tr.hasClass('member-wait') && (isNaN(estimate) || estimate <= 0)) + { + zui.Modal.alert(account + ' ' + estimateNotEmpty); + error = true; + return false; + } + + let $left = $tr.find('[name^=teamLeft]'); + let left = parseFloat($left.val()); + if(!$left.prop('readonly') && $tr.hasClass('member-wait') && (isNaN(left) || left <= 0)) + { + zui.Modal.alert(account + ' ' + leftNotEmpty); + error = true; + return false; + } + }); + + if(error) return false; + + if(memberCount < 2) + { + zui.Modal.alert(teamMemberError); + return false; + } +} diff --git a/module/task/ui/edit.html.php b/module/task/ui/edit.html.php index 29b6e9f296..bebf1e0093 100644 --- a/module/task/ui/edit.html.php +++ b/module/task/ui/edit.html.php @@ -350,7 +350,7 @@ detailBody set::title($lang->task->teamMember), h::table ( - set::id('teamTable'), + setID('teamTable'), setClass('table table-form'), $teamForm, h::tr diff --git a/module/task/ui/manageteam.html.php b/module/task/ui/manageteam.html.php index ab92f5907a..f341f9b8c2 100644 --- a/module/task/ui/manageteam.html.php +++ b/module/task/ui/manageteam.html.php @@ -4,132 +4,55 @@ declare(strict_types=1); * The manageteam view file of task module of ZenTaoPMS. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) - * @author zenggang + * @author Shujie Tian * @package task * @link https://www.zentao.net */ namespace zin; - -formPanel -( - set::title($formTitle), // The form title is diffrent from the page title, - formRow +if(!isset($task->members[$app->user->account])) +{ + div ( - formGroup + setClass('alert with-icon my-8'), + icon('exclamation-sign text-gray'), + div ( - set::width("1/3"), - set::name("team[]"), - set::value("productManager"), - set::control("picker"), - set::id("team"), - set::items($teamOptions) - ), - formGroup - ( - set::width("1/3"), - inputGroup - ( - - ) + setClass('content'), + html(sprintf($lang->task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->transfer)) ) - ), - formRow + ); +} +else +{ + include './taskteam.html.php'; + jsVar('teamMemberError', $lang->task->error->teamMember); + jsVar('totalLeftError', sprintf($this->lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status])); + jsVar('estimateNotEmpty', sprintf($lang->error->gt, $lang->task->estimate, '0')); + jsVar('leftNotEmpty', sprintf($lang->error->gt, $lang->task->left, '0')); + + to::header ( - formGroup + entityLabel ( - set::width("1/3"), - set::name("team[]"), - set::value("zenggang"), - set::control("picker"), - set::id("team"), - set::items($teamOptions) - ), - formGroup - ( - set::width("1/3"), - inputGroup - ( - - ) + set::level(1), + setClass('clip w-full'), + set::text($lang->task->team . ' > ' . $task->name) ) - ), - formRow + ); + + formPanel ( - formGroup + setID('teamForm'), + set::url(inlink('manageTeam', "executionID=$task->execution&taskID=$task->id")), + set::ajax(array('beforeSubmit' => jsRaw("clickSubmit"))), + h::table ( - set::width("1/3"), - set::name("team[]"), - set::control("picker"), - set::id("team"), - set::items($teamOptions) - ), - formGroup - ( - set::width("1/3"), - inputGroup - ( - - ) + setID('teamTable'), + setClass('table table-form'), + formHidden('mode', $task->mode), + $teamForm ) - ), - formRow - ( - formGroup - ( - set::width("1/3"), - set::name("team[]"), - set::control("picker"), - set::id("team"), - set::items($teamOptions) - ), - formGroup - ( - set::width("1/3"), - inputGroup - ( - - ) - ) - ), - formRow - ( - formGroup - ( - set::width("1/3"), - set::name("team[]"), - set::control("picker"), - set::id("team"), - set::items($teamOptions) - ), - formGroup - ( - set::width("1/3"), - inputGroup - ( - - ) - ) - ), - formRow - ( - formGroup - ( - set::width("1/3"), - set::name("team[]"), - set::control("picker"), - set::id("team"), - set::items($teamOptions) - ), - formGroup - ( - set::width("1/3"), - inputGroup - ( - - ) - ) - ) -); + ); +} render(); - From b361a59de391261e7c081f8d50354115461c4266 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 15:07:41 +0800 Subject: [PATCH 056/235] * project: fix spell error. --- module/project/js/common.ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 7e03fb32fa..baea0d2259 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -90,7 +90,7 @@ function computeWorkDays() if(end == LONG_TIME) { $('#delta999').prop('checked', true); - $('#days').val(0).tigger('change'); + $('#days').val(0).trigger('change'); } else { From 39b961bb0be0d86d33c7bf7eadd012e51c18633b Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 15:10:54 +0800 Subject: [PATCH 057/235] * project: add a hidden inputControl to display the end date of long time project. --- module/project/ui/edit.html.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/module/project/ui/edit.html.php b/module/project/ui/edit.html.php index e50325fcde..1273191b15 100644 --- a/module/project/ui/edit.html.php +++ b/module/project/ui/edit.html.php @@ -330,7 +330,17 @@ formPanel set::value($project->end), set::placeholder($lang->project->end), set::required(true), - set::disabled($project->end == LONG_TIME) + $project->end == LONG_TIME ? setClass('hidden') : null + ), + inputControl + ( + setClass('has-suffix-icon w-full' . ($project->end != LONG_TIME ? ' hidden' : '')), + to::suffix(icon('calendar')), + input + ( + set::value($lang->project->longTime), + set::disabled(true) + ) ) ) ), From ed9ee29139b8a2db0de8dc0510b4254f8044a2b0 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 15:18:43 +0800 Subject: [PATCH 058/235] * project: modify, merge and sort code to bind javascript functions to html tags. --- module/project/ui/edit.html.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/project/ui/edit.html.php b/module/project/ui/edit.html.php index 1273191b15..49df563330 100644 --- a/module/project/ui/edit.html.php +++ b/module/project/ui/edit.html.php @@ -3,6 +3,7 @@ namespace zin; jsVar('model', $project->model); jsVar('labelClass', $config->project->labelClass); +jsVar('LONG_TIME', LONG_TIME); jsVar('longTime', $lang->project->longTime); jsVar('weekend', $config->execution->weekend); jsVar('unmodifiableProducts', $unmodifiableProducts); @@ -172,12 +173,11 @@ formPanel on::click('.project-type-0', 'changeType(0)'), on::click('.project-stageBy-0', 'changeStageBy(0)'), on::click('.project-stageBy-1', 'changeStageBy(1)'), + on::change('#parent', 'setParentProgram'), + on::change('#begin, [name=delta]', 'computeEndDate'), + on::change('#begin, #end', 'computeWorkDays'), on::change('[name^=products]', 'productChange'), on::change('[name^=branch]', 'branchChange'), - on::change('#parent', 'setParentProgram'), - on::change('#begin', 'computeWorkDays'), - on::change('#end', 'computeWorkDays'), - on::change('[name=delta]', 'setDate'), on::change('[name=future]', 'toggleBudget'), on::change('[name=newProduct]', 'addProduct'), formRow From db7dbb174ea7b807c2fb0b80ff473503ac0da2d3 Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 07:21:38 +0000 Subject: [PATCH 059/235] * Set value for picker items. --- module/stakeholder/control.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/stakeholder/control.php b/module/stakeholder/control.php index 21ede72b2c..fdf3110614 100644 --- a/module/stakeholder/control.php +++ b/module/stakeholder/control.php @@ -213,7 +213,7 @@ class stakeholder extends control } $items = array(); - foreach($members as $account => $realname) $items[] = array('key' => $account, 'text' => $realname); + foreach($members as $account => $realname) $items[] = array('value' => $account, 'text' => $realname); return print(json_encode($items)); } @@ -247,7 +247,7 @@ class stakeholder extends control } $userItems = array(); - foreach($companyUsers as $account => $realname) $userItems[] = array('text' => $realname, 'key' => $account); + foreach($companyUsers as $account => $realname) $userItems[] = array('text' => $realname, 'value' => $account); return print(json_encode($userItems)); } @@ -268,7 +268,7 @@ class stakeholder extends control } $items = array(); - foreach($users as $account => $realname) $items[] = array('text' => $realname, 'key' => $account); + foreach($users as $account => $realname) $items[] = array('text' => $realname, 'value' => $account); return print(json_encode($items)); } From 51e93ad784d4f77e3c59ac0726f4f55437b2154c Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 07:22:36 +0000 Subject: [PATCH 060/235] * Optimize codes. --- module/stakeholder/js/create.ui.js | 38 +++++---------------------- module/stakeholder/lang/de.php | 3 --- module/stakeholder/lang/en.php | 3 --- module/stakeholder/lang/fr.php | 3 --- module/stakeholder/lang/vi.php | 3 --- module/stakeholder/lang/zh-cn.php | 3 --- module/stakeholder/model.php | 28 ++++++-------------- module/stakeholder/ui/create.html.php | 9 ++++--- 8 files changed, 20 insertions(+), 70 deletions(-) diff --git a/module/stakeholder/js/create.ui.js b/module/stakeholder/js/create.ui.js index e1f7a08895..704f1d5915 100644 --- a/module/stakeholder/js/create.ui.js +++ b/module/stakeholder/js/create.ui.js @@ -10,6 +10,7 @@ function toggleUser() if($(this).val() == 'outside') var link = $.createLink('stakeholder', 'ajaxGetOutsideUser', 'objectID=' + programID ? programID : projectID); $.getJSON(link, function(users) { + console.log(users); let $userPicker = $('[name^="user"]').zui('picker'); $userPicker.render({items: users}); $userPicker.$.setValue(''); @@ -44,40 +45,15 @@ function onChooseCompany(event) * * @return void */ -function onChangeNewCompany(event) +function toggleCompany() { - const checkbox = $(event.target); - const checkboxChecked = checkbox.prop('checked'); - const companyInput = $('#company'); - const companySelect = $('[name="companySelect"]'); + let $companyPicker = $('[name^="company"]').zui('picker'); /* Reset empty default value. */ - companyInput.prop('value', ''); - companySelect.prop('value', ''); + $('#companyName').val(''); + $companyPicker.$.setValue(''); - /* Switch between 'select' and 'input'. */ - if(checkboxChecked) - { - checkbox.prop('value', 1); - companyInput.removeClass('hidden'); - companyInput.trigger('focus'); - companySelect.addClass('hidden'); - } - else - { - checkbox.prop('value', 0); - companyInput.removeClass('hidden'); - companyInput.addClass('hidden'); - companySelect.removeClass('hidden'); - companySelect.trigger('focus'); - } + $('#companyName').toggleClass('hidden', !$(this).prop('checked')); - /* Remove error tips and error style. */ - companyInput.removeClass('has-error'); - companySelect.removeClass('has-error'); - const tip = checkbox.parents('.form-group').children('.form-tip'); - if(tip) - { - tip.remove(); - } + $('.company-picker').toggleClass('hidden', $(this).prop('checked')); } diff --git a/module/stakeholder/lang/de.php b/module/stakeholder/lang/de.php index 3a68481b18..12bd9650da 100644 --- a/module/stakeholder/lang/de.php +++ b/module/stakeholder/lang/de.php @@ -55,9 +55,6 @@ $lang->stakeholder->fromList['team'] = $lang->projectCommon . ' Team'; $lang->stakeholder->fromList['company'] = 'Internal'; $lang->stakeholder->fromList['outside'] = 'External'; -$lang->stakeholder->userEmpty = 'User cannot be empty!'; -$lang->stakeholder->nameEmpty = 'Name cannot be empty!'; -$lang->stakeholder->companyEmpty = 'Company cannot be empty!'; $lang->stakeholder->confirmDelete = "Do you want to delete the stakeholder?"; $lang->stakeholder->confirmDeleteExpect = "Do you want to remove the expectation?"; $lang->stakeholder->createCommunicate = 'added Communication History.'; diff --git a/module/stakeholder/lang/en.php b/module/stakeholder/lang/en.php index 5270372c38..bb0e625455 100644 --- a/module/stakeholder/lang/en.php +++ b/module/stakeholder/lang/en.php @@ -55,9 +55,6 @@ $lang->stakeholder->fromList['team'] = $lang->projectCommon . ' Team'; $lang->stakeholder->fromList['company'] = 'Internal'; $lang->stakeholder->fromList['outside'] = 'External'; -$lang->stakeholder->userEmpty = 'User cannot be empty!'; -$lang->stakeholder->nameEmpty = 'Name cannot be empty!'; -$lang->stakeholder->companyEmpty = 'Company cannot be empty!'; $lang->stakeholder->confirmDelete = "Do you want to delete the stakeholder?"; $lang->stakeholder->confirmDeleteExpect = "Do you want to remove the expectation?"; $lang->stakeholder->createCommunicate = 'added Communication History.'; diff --git a/module/stakeholder/lang/fr.php b/module/stakeholder/lang/fr.php index 3a68481b18..12bd9650da 100644 --- a/module/stakeholder/lang/fr.php +++ b/module/stakeholder/lang/fr.php @@ -55,9 +55,6 @@ $lang->stakeholder->fromList['team'] = $lang->projectCommon . ' Team'; $lang->stakeholder->fromList['company'] = 'Internal'; $lang->stakeholder->fromList['outside'] = 'External'; -$lang->stakeholder->userEmpty = 'User cannot be empty!'; -$lang->stakeholder->nameEmpty = 'Name cannot be empty!'; -$lang->stakeholder->companyEmpty = 'Company cannot be empty!'; $lang->stakeholder->confirmDelete = "Do you want to delete the stakeholder?"; $lang->stakeholder->confirmDeleteExpect = "Do you want to remove the expectation?"; $lang->stakeholder->createCommunicate = 'added Communication History.'; diff --git a/module/stakeholder/lang/vi.php b/module/stakeholder/lang/vi.php index a59ba2f632..5852779b16 100644 --- a/module/stakeholder/lang/vi.php +++ b/module/stakeholder/lang/vi.php @@ -60,9 +60,6 @@ $lang->stakeholder->fromList['team'] = 'Project Team'; $lang->stakeholder->fromList['company'] = 'Internal'; $lang->stakeholder->fromList['outside'] = 'External'; -$lang->stakeholder->userEmpty = 'User cannot be empty!'; -$lang->stakeholder->nameEmpty = 'Name cannot be empty!'; -$lang->stakeholder->companyEmpty = 'Company cannot be empty!'; $lang->stakeholder->confirmDelete = "Do you want to delete the stakeholder?"; $lang->stakeholder->confirmDeleteExpect = "Do you want to remove the expectation?"; $lang->stakeholder->createCommunicate = 'added Communication History.'; diff --git a/module/stakeholder/lang/zh-cn.php b/module/stakeholder/lang/zh-cn.php index 954419d463..f587823840 100644 --- a/module/stakeholder/lang/zh-cn.php +++ b/module/stakeholder/lang/zh-cn.php @@ -55,9 +55,6 @@ $lang->stakeholder->fromList['team'] = $lang->projectCommon . '团队成员'; $lang->stakeholder->fromList['company'] = '公司同事'; $lang->stakeholder->fromList['outside'] = '外部人员'; -$lang->stakeholder->userEmpty = '用户不能为空!'; -$lang->stakeholder->nameEmpty = '姓名不能为空!'; -$lang->stakeholder->companyEmpty = '所属公司不能为空!'; $lang->stakeholder->confirmDelete = "您确定删除该干系人吗?"; $lang->stakeholder->confirmDeleteExpect = "您确定删除该干系人期望吗?"; $lang->stakeholder->createCommunicate = '添加沟通记录'; diff --git a/module/stakeholder/model.php b/module/stakeholder/model.php index 5a64587d7c..257881d19d 100644 --- a/module/stakeholder/model.php +++ b/module/stakeholder/model.php @@ -17,7 +17,6 @@ class stakeholderModel extends model ->setDefault('createdDate', helper::today()) ->stripTags($this->config->stakeholder->editor->create['id'], $this->config->allowedTags) ->remove('uid') - ->remove('companySelect') ->get(); $account = isset($data->user) ? $data->user : ''; @@ -40,29 +39,21 @@ class stakeholderModel extends model /* If it's an outsider and it's added for the first time, insert to user table. */ if(!$account) { - if(!$data->name) - { - dao::$errors['name'] = $this->lang->stakeholder->nameEmpty; - return false; - } + if(!$data->name) dao::$errors['name'] = sprintf($this->lang->error->notempty, $this->lang->stakeholder->name); + if(!isset($data->newCompany) && !$data->company) dao::$errors['company'] = sprintf($this->lang->error->notempty, $this->lang->stakeholder->company); + if(isset($data->newCompany) && !$data->companyName) dao::$errors['company'] = sprintf($this->lang->error->notempty, $this->lang->stakeholder->company); + if(dao::isError()) return false; $companyID = $data->company; - if($data->company and isset($data->new)) + if(isset($data->newCompany) && $data->companyName) { $company = new stdclass(); - $company->name = $data->company; - $this->dao->insert(TABLE_COMPANY)->data($company)->exec(); + $company->name = $data->companyName; + $this->dao->insert(TABLE_COMPANY)->data($company)->autoCheck()->exec(); $companyID = $this->dao->lastInsertID(); } - if(!$companyID) - { - $elementName = $data->new ? 'company' : 'companySelect'; - dao::$errors[$elementName] = $this->lang->stakeholder->companyEmpty; - return false; - } - $user = new stdclass(); $user->type = 'outside'; $user->realname = $data->name; @@ -93,10 +84,7 @@ class stakeholderModel extends model $stakeholder->createdBy = $this->app->user->account; $stakeholder->createdDate = helper::today(); - $this->dao->insert(TABLE_STAKEHOLDER)->data($stakeholder) - ->check('user', 'unique', "objectID = {$stakeholder->objectID} and deleted = '0'") - ->autoCheck() - ->exec(); + $this->dao->insert(TABLE_STAKEHOLDER)->data($stakeholder)->check('user', 'unique', "objectID = {$stakeholder->objectID} and deleted = '0'")->autoCheck()->exec(); $stakeholderID = $this->dao->lastInsertID(); if(!dao::isError()) diff --git a/module/stakeholder/ui/create.html.php b/module/stakeholder/ui/create.html.php index 41e6d5e6ed..44613b5ae7 100644 --- a/module/stakeholder/ui/create.html.php +++ b/module/stakeholder/ui/create.html.php @@ -26,7 +26,7 @@ formPanel ( on::change('[name=from]', 'toggleUser'), on::change('[name=newUser]', 'toggleNewUserInfo'), - on::change('[name=new]', 'onChooseCompany'), + on::change('[name=newCompany]', 'toggleCompany'), set::url(createLink('stakeholder', 'create', "objectID=$objectID")), to::heading(div ( @@ -140,12 +140,13 @@ formPanel ( picker ( - set::name('companySelect'), + setClass('company-picker'), + set::name('company'), set::items($companys) ), input ( - set::name('company'), + set::name('companyName'), setClass('hidden') ), span @@ -153,7 +154,7 @@ formPanel setClass('input-group-addon'), checkbox ( - set::name('new'), + set::name('newCompany'), set::text($lang->stakeholder->add) ) ) From a30cd3d2ce8062ca0525e5d6f393118cf72ab368 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 15:23:11 +0800 Subject: [PATCH 061/235] * Fixed the error when add task and back to execution story page. --- module/admin/ui/checkweak.html.php | 2 +- module/admin/ui/safe.html.php | 6 ++--- module/block/ui/assigntomeblock.html.php | 20 ++++++++--------- module/block/ui/projectblock.html.php | 2 +- module/execution/ui/story.html.php | 10 ++++----- module/task/ui/create.html.php | 28 ++++++++++++------------ 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/module/admin/ui/checkweak.html.php b/module/admin/ui/checkweak.html.php index 48c2a75959..bc7d37aa3a 100644 --- a/module/admin/ui/checkweak.html.php +++ b/module/admin/ui/checkweak.html.php @@ -53,7 +53,7 @@ $tableData = initTableData($weakUsers, $config->admin->checkWeak->dtable->fieldL div ( - set::id('mainContent'), + setID('mainContent'), setClass('row has-sidebar-left'), $menuItems ? sidebar ( diff --git a/module/admin/ui/safe.html.php b/module/admin/ui/safe.html.php index bf2b862e94..7facb8e8fa 100644 --- a/module/admin/ui/safe.html.php +++ b/module/admin/ui/safe.html.php @@ -53,7 +53,7 @@ if(common::hasPriv('admin', 'resetPWDSetting')) div ( - set::id('mainContent'), + setID('mainContent'), setClass('row has-sidebar-left'), $menuItems ? sidebar ( @@ -103,7 +103,7 @@ div ), formRow ( - set::id('mode1Rule'), + setID('mode1Rule'), $config->safe->mode != 1 ? setClass('hidden') : '', formGroup ( @@ -121,7 +121,7 @@ div ), formRow ( - set::id('mode2Rule'), + setID('mode2Rule'), $config->safe->mode != 2 ? setClass('hidden') : '', formGroup ( diff --git a/module/block/ui/assigntomeblock.html.php b/module/block/ui/assigntomeblock.html.php index df5652eabf..88b92f970f 100644 --- a/module/block/ui/assigntomeblock.html.php +++ b/module/block/ui/assigntomeblock.html.php @@ -31,11 +31,11 @@ foreach($hasViewPriv as $type => $bool) { $menus[] = li ( - set('class', 'nav-item nav-switch'), + setClass('nav-item nav-switch'), a ( - set('class', $type == $selected ? 'active' : ''), - set('data-toggle', 'tab'), + setClass($type == $selected ? 'active' : ''), + setData(array('toggle' => 'tab')), set('href', "#assigntome{$type}Tab{$blockNavCode}"), $type == 'review' ? $lang->my->audit : zget($lang->block->availableBlocks, $type) ) @@ -48,18 +48,18 @@ if(($longBlock && $count > 9) || (!$longBlock && $count > 4)) { $menus[] = li ( - set('class', 'nav-item nav-switch'), + setClass('nav-item nav-switch'), a ( - set('data-toggle', 'dropdown'), + setData(array('toggle' => 'dropdown')), set('href', "#assigntomeMenuMore{$blockNavCode}"), span($lang->more), icon('caret-down') ), menu ( - set::id("assigntomeMenuMore{$blockNavCode}"), - set::className('dropdown-menu'), + setID("assigntomeMenuMore{$blockNavCode}"), + setClass('dropdown-menu'), set::items($moreMenus) ) ); @@ -102,8 +102,8 @@ foreach($hasViewPriv as $type => $bool) $selected = key($hasViewPriv); $contents[] = div ( - set('class', 'tab-pane ' . ($type == $selected ? 'active' : '')), - set('id', "assigntome{$type}Tab{$blockNavCode}"), + setClass('tab-pane ' . ($type == $selected ? 'active' : '')), + setID("assigntome{$type}Tab{$blockNavCode}"), dtable ( set::height(318), @@ -127,7 +127,7 @@ blockPanel ( ul ( - set('class', 'nav nav-tabs'), + setClass('nav nav-tabs'), $menus ) ) diff --git a/module/block/ui/projectblock.html.php b/module/block/ui/projectblock.html.php index f7c582a4d8..e37de8e935 100644 --- a/module/block/ui/projectblock.html.php +++ b/module/block/ui/projectblock.html.php @@ -30,7 +30,7 @@ blockPanel setClass('list-block'), dtable ( - set::id('project'), + setID('project'), set::height(318), set::bordered(false), set::horzScrollbarPos('inside'), diff --git a/module/execution/ui/story.html.php b/module/execution/ui/story.html.php index 69ec558ba5..5605890aa3 100644 --- a/module/execution/ui/story.html.php +++ b/module/execution/ui/story.html.php @@ -225,7 +225,7 @@ modal set::text($lang->execution->next), set::btnType('submit'), set::type('primary'), - set('data-dismiss', 'primary') + setData(array('dismiss' => 'primary')) ) ) ); @@ -248,8 +248,8 @@ if($canBatchAction) { menu ( - set::id('batchToTask'), - set::className('dropdown-menu'), + setID('batchToTask'), + setClass('dropdown-menu'), $canBatchToTask ? item(set(array( 'text' => $lang->story->batchToTask, 'url' => '#taskModal', @@ -347,7 +347,7 @@ foreach($setting as $col) if(!$execution->hasProduct and !$execution->multiple and $value['name'] == 'plan') continue; if(!$execution->hasProduct and !$execution->multiple and $storyType == 'requirement' and $value['name'] == 'stage') continue; - if($col['name'] == 'title') $col['link'] = sprintf($col['link'], createLink('execution', 'storyView', array('storyID' => '{id}', 'execution' => $execution->id))); + if($col['name'] == 'title') $col['link'] = sprintf(zget($col['link'], 'url'), createLink('execution', 'storyView', array('storyID' => '{id}', 'execution' => $execution->id))); $cols[] = $col; } @@ -373,12 +373,12 @@ jsVar('summary', $summary); jsVar('checkedSummary', str_replace('%storyCommon%', $lang->SRCommon, $lang->product->checkedSummary)); dtable ( + setClass('shadow rounded'), set::userMap($users), set::customCols(true), set::groupDivider(true), set::cols($cols), set::data($data), - set::className('shadow rounded'), set::footToolbar($footToolbar), set::onRenderCell(jsRaw('window.renderStoryCell')), set::orderBy($orderBy), diff --git a/module/task/ui/create.html.php b/module/task/ui/create.html.php index 53f0e0094a..93e5389a1e 100644 --- a/module/task/ui/create.html.php +++ b/module/task/ui/create.html.php @@ -120,7 +120,7 @@ else $storyPreviewBtn = span ( setClass('input-group-btn flex hidden'), - set::id('preview'), + setID('preview'), modalTrigger ( to::trigger( @@ -189,7 +189,7 @@ $selectStoryRow = ''; if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))) { $selectStoryRow = formRow( - set::id('testStoryBox'), + setID('testStoryBox'), setClass('hidden') ); } @@ -216,7 +216,7 @@ if(!isAjaxRequest('modal')) formPanel ( - set::id('taskCreateForm'), + setID('taskCreateForm'), set::title($lang->task->create), $from == 'task' ? set::customFields(true) : null, formRow @@ -237,7 +237,7 @@ formPanel ), span ( - set('class', 'input-group-btn'), + setClass('input-group-btn'), btn ( setID('showAllModuleButton'), @@ -269,10 +269,10 @@ formPanel formGroup ( set::width('1/2'), - set::id('selectTestStoryBox'), + setID('selectTestStoryBox'), setClass('hidden items-center'), checkbox( - set::id('selectTestStory'), + setID('selectTestStory'), set::name('selectTestStory'), set::value(1), set::text($lang->task->selectTestStory), @@ -289,7 +289,7 @@ formPanel setClass('assignedToBox'), picker ( - set::id('assignedTo'), + setID('assignedTo'), set::name('assignedTo'), set::value($task->assignedTo), set::items($members) @@ -313,7 +313,7 @@ formPanel formGroup ( set::width('1/10'), - set::id('multipleBox'), + setID('multipleBox'), setClass('items-center'), checkbox( set::name('multiple'), @@ -343,7 +343,7 @@ formPanel ( picker ( - set::id('story'), + setID('story'), set::name('story'), set::value($task->story), set::items(array_filter($stories)), @@ -370,7 +370,7 @@ formPanel setClass('input-control-suffix'), btn( setClass('text-gray'), - set::id('refreshStories'), + setID('refreshStories'), set::icon('refresh'), on::click('loadExecutionStories') ) @@ -404,7 +404,7 @@ formPanel set::syncColor('#name') ), checkbox( - set::id('copyButton'), + setID('copyButton'), set::name('copyButton'), set::value(1), set::text($lang->task->copyStoryTitle), @@ -442,7 +442,7 @@ formPanel ), inputControl ( - set::className($hiddenEstimate), + setClass($hiddenEstimate), input(set::name('estimate')), to::suffix($lang->task->suffixHour), set::suffixWidth(20) @@ -511,11 +511,11 @@ formPanel ( modal ( - set::id('modalTeam'), + setID('modalTeam'), set::title($lang->task->teamMember), h::table ( - set::id('teamTable'), + setID('teamTable'), h::tr ( h::td From ceba4323b6b5edd2eda92dd9a1cb015dfbf1618e Mon Sep 17 00:00:00 2001 From: sunguangming Date: Thu, 16 Nov 2023 15:27:23 +0800 Subject: [PATCH 062/235] * Merge code. --- module/action/lang/de.php | 5 ++ module/action/lang/en.php | 7 ++- module/action/lang/fr.php | 5 ++ module/action/lang/vi.php | 4 ++ module/action/lang/zh-cn.php | 5 ++ module/task/css/common.ui.css | 2 - module/task/ui/create.html.php | 90 ++++++++++++++++------------------ 7 files changed, 67 insertions(+), 51 deletions(-) diff --git a/module/action/lang/de.php b/module/action/lang/de.php index 62cf122c53..797a0775d6 100644 --- a/module/action/lang/de.php +++ b/module/action/lang/de.php @@ -202,6 +202,7 @@ $lang->action->desc->restarted = '$date, continued by $actor< $lang->action->desc->delayed = '$date, zurückgestellt von $actor.' . "\n"; $lang->action->desc->suspended = '$date, ausgesetzt von $actor.' . "\n"; $lang->action->desc->recordworkhour = '$date, aufgenommen von $actor und hat $extra Stunden aufgebraucht.'; +$lang->action->desc->recordestimate = '$date, aufgenommen von $actor und hat $extra Stunden aufgebraucht.'; $lang->action->desc->editestimate = '$date, $actor Stunden angepaast.'; $lang->action->desc->deleteestimate = '$date, $actor Stunden gelöscht.'; $lang->action->desc->canceled = '$date, abgebrochen von $actor.' . "\n"; @@ -395,6 +396,7 @@ $lang->action->label->unlinkchildstory = "Unlink"; $lang->action->label->started = 'started '; $lang->action->label->restarted = 'continued '; $lang->action->label->recordworkhour = 'recorded '; +$lang->action->label->recordestimate = 'recorded '; $lang->action->label->editestimate = 'edited '; $lang->action->label->canceled = 'cancelled '; $lang->action->label->finished = 'finished '; @@ -640,6 +642,7 @@ $lang->action->dynamicAction->task['confirmed'] = 'Confirm Task'; $lang->action->dynamicAction->task['started'] = 'Start Task'; $lang->action->dynamicAction->task['finished'] = 'Finish Task'; $lang->action->dynamicAction->task['recordworkhour'] = 'Add Estimates'; +$lang->action->dynamicAction->task['recordestimate'] = 'Add Estimates'; $lang->action->dynamicAction->task['editestimate'] = 'Edit Estimates'; $lang->action->dynamicAction->task['deleteestimate'] = 'Delete Estimates'; $lang->action->dynamicAction->task['paused'] = 'Pause Task'; @@ -909,6 +912,7 @@ $lang->action->search->label['linked2kanban'] = $lang->action->label->li $lang->action->search->label['started'] = $lang->action->label->started; $lang->action->search->label['restarted'] = $lang->action->label->restarted; $lang->action->search->label['recordworkhour'] = $lang->action->label->recordworkhour; +$lang->action->search->label['recordestimate'] = $lang->action->label->recordworkhour; $lang->action->search->label['editestimate'] = $lang->action->label->editestimate; $lang->action->search->label['canceled'] = $lang->action->label->canceled; $lang->action->search->label['finished'] = $lang->action->label->finished; @@ -944,6 +948,7 @@ $lang->action->apiTitle->restarted = 'Continued by $actoraction->apiTitle->delayed = 'Postponed by $actor.'; $lang->action->apiTitle->suspended = 'Suspended by $actor.'; $lang->action->apiTitle->recordworkhour = 'Recorded by $actor and it cost $extra hours.'; +$lang->action->apiTitle->recordestimate = 'Recorded by $actor and it cost $extra hours.'; $lang->action->apiTitle->editestimate = '$actor edited Hour.'; $lang->action->apiTitle->deleteestimate = '$actor deleted Hour.'; $lang->action->apiTitle->canceled = 'Cancelled by $actor.'; diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 640d9f6486..634e11d0cd 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -202,6 +202,7 @@ $lang->action->desc->restarted = '$date, continued by $actor< $lang->action->desc->delayed = '$date, postponed by $actor.' . "\n"; $lang->action->desc->suspended = '$date, suspended by $actor.' . "\n"; $lang->action->desc->recordworkhour = '$date, recorded by $actor and it cost $extra hours.'; +$lang->action->desc->recordestimate = '$date, recorded by $actor and it cost $extra hours.'; $lang->action->desc->editestimate = '$date, $actor edited Hour.'; $lang->action->desc->deleteestimate = '$date, $actor deleted Hour.'; $lang->action->desc->canceled = '$date, cancelled by $actor.' . "\n"; @@ -398,6 +399,7 @@ $lang->action->label->unlinkchildstory = "unlinked Story "; $lang->action->label->started = 'started '; $lang->action->label->restarted = 'continued '; $lang->action->label->recordworkhour = 'recorded '; +$lang->action->label->recordestimate = 'recorded '; $lang->action->label->editestimate = 'edited '; $lang->action->label->canceled = 'cancelled '; $lang->action->label->finished = 'finished '; @@ -643,7 +645,8 @@ $lang->action->dynamicAction->task['assigned'] = 'Assign Task'; $lang->action->dynamicAction->task['confirmed'] = 'Confirm Task'; $lang->action->dynamicAction->task['started'] = 'Start Task'; $lang->action->dynamicAction->task['finished'] = 'Finish Task'; -$lang->action->dynamicAction->task['recordworkhour'] = 'Add Estimates'; +$lang->action->dynamicAction->task['recordworkhour'] = 'Add Workhour'; +$lang->action->dynamicAction->task['recordestimate'] = 'Add Workhour'; $lang->action->dynamicAction->task['editestimate'] = 'Edit Estimates'; $lang->action->dynamicAction->task['deleteestimate'] = 'Delete Estimates'; $lang->action->dynamicAction->task['paused'] = 'Pause Task'; @@ -920,6 +923,7 @@ $lang->action->search->label['linked2kanban'] = $lang->action->label->li $lang->action->search->label['started'] = $lang->action->label->started; $lang->action->search->label['restarted'] = $lang->action->label->restarted; $lang->action->search->label['recordworkhour'] = $lang->action->label->recordworkhour; +$lang->action->search->label['recordestimate'] = $lang->action->label->recordworkhour; $lang->action->search->label['editestimate'] = $lang->action->label->editestimate; $lang->action->search->label['canceled'] = $lang->action->label->canceled; $lang->action->search->label['finished'] = $lang->action->label->finished; @@ -955,6 +959,7 @@ $lang->action->apiTitle->restarted = 'Continued by $actoraction->apiTitle->delayed = 'Postponed by $actor.'; $lang->action->apiTitle->suspended = 'Suspended by $actor.'; $lang->action->apiTitle->recordworkhour = 'Recorded by $actor and it cost $extra hours.'; +$lang->action->apiTitle->recordestimate = 'Recorded by $actor and it cost $extra hours.'; $lang->action->apiTitle->editestimate = '$actor edited Hour.'; $lang->action->apiTitle->deleteestimate = '$actor deleted Hour.'; $lang->action->apiTitle->canceled = 'Cancelled by $actor.'; diff --git a/module/action/lang/fr.php b/module/action/lang/fr.php index 8d0f3b61c9..72754aa4a1 100644 --- a/module/action/lang/fr.php +++ b/module/action/lang/fr.php @@ -202,6 +202,7 @@ $lang->action->desc->restarted = '$date, reprise par $actoraction->desc->delayed = '$date, ajourné par $actor.' . "\n"; $lang->action->desc->suspended = '$date, suspendu par $actor.' . "\n"; $lang->action->desc->recordworkhour = '$date, enregistré par $actor et son coût est de $extra heures.'; +$lang->action->desc->recordestimate = '$date, enregistré par $actor et son coût est de $extra heures.'; $lang->action->desc->editestimate = '$date, $actor a édité son temps estimé.'; $lang->action->desc->deleteestimate = '$date, $actor a supprimé son estimation de temps.'; $lang->action->desc->canceled = '$date, annulé par $actor.' . "\n"; @@ -395,6 +396,7 @@ $lang->action->label->unlinkchildstory = "a dissocié de la Story fille " $lang->action->label->started = 'a commencé '; $lang->action->label->restarted = 'a continué '; $lang->action->label->recordworkhour = 'a estimé '; +$lang->action->label->recordestimate = 'a estimé '; $lang->action->label->editestimate = 'a réestimé '; $lang->action->label->canceled = 'a annulé '; $lang->action->label->finished = 'a fini '; @@ -640,6 +642,7 @@ $lang->action->dynamicAction->task['confirmed'] = 'Confirmer Tâche'; $lang->action->dynamicAction->task['started'] = 'Commencer Tâche'; $lang->action->dynamicAction->task['finished'] = 'Terminer Tâche'; $lang->action->dynamicAction->task['recordworkhour'] = 'Ajouter Estimation'; +$lang->action->dynamicAction->task['recordestimate'] = 'Ajouter Estimation'; $lang->action->dynamicAction->task['editestimate'] = 'Editer Estimation'; $lang->action->dynamicAction->task['deleteestimate'] = 'RAZ Estimation'; $lang->action->dynamicAction->task['paused'] = 'Stopper Tâche'; @@ -909,6 +912,7 @@ $lang->action->search->label['linked2kanban'] = $lang->action->label->li $lang->action->search->label['started'] = $lang->action->label->started; $lang->action->search->label['restarted'] = $lang->action->label->restarted; $lang->action->search->label['recordworkhour'] = $lang->action->label->recordworkhour; +$lang->action->search->label['recordestimate'] = $lang->action->label->recordworkhour; $lang->action->search->label['editestimate'] = $lang->action->label->editestimate; $lang->action->search->label['canceled'] = $lang->action->label->canceled; $lang->action->search->label['finished'] = $lang->action->label->finished; @@ -944,6 +948,7 @@ $lang->action->apiTitle->restarted = 'Continued by $actoraction->apiTitle->delayed = 'Postponed by $actor.'; $lang->action->apiTitle->suspended = 'Suspended by $actor.'; $lang->action->apiTitle->recordworkhour = 'Recorded by $actor and it cost $extra hours.'; +$lang->action->apiTitle->recordestimate = 'Recorded by $actor and it cost $extra hours.'; $lang->action->apiTitle->editestimate = '$actor edited Hour.'; $lang->action->apiTitle->deleteestimate = '$actor deleted Hour.'; $lang->action->apiTitle->canceled = 'Cancelled by $actor.'; diff --git a/module/action/lang/vi.php b/module/action/lang/vi.php index 231f1c2923..d9ed8d888d 100644 --- a/module/action/lang/vi.php +++ b/module/action/lang/vi.php @@ -164,6 +164,7 @@ $lang->action->desc->restarted = '$date, continued by $actoraction->desc->delayed = '$date, postponed by $actor.' . "\n"; $lang->action->desc->suspended = '$date, suspended by $actor.' . "\n"; $lang->action->desc->recordworkhour = '$date, ghi nhận bởi $actor and it cost $extra giờ.'; +$lang->action->desc->recordestimate = '$date, ghi nhận bởi $actor and it cost $extra giờ.'; $lang->action->desc->editestimate = '$date, $actor edited Hour.'; $lang->action->desc->deleteestimate = '$date, $actor deleted Hour.'; $lang->action->desc->canceled = '$date, cancelled by $actor.' . "\n"; @@ -314,6 +315,7 @@ $lang->action->label->unlinkchildstory = "hủy liên kết Story "; $lang->action->label->started = 'started '; $lang->action->label->restarted = 'continued '; $lang->action->label->recordworkhour = 'recorded '; +$lang->action->label->recordestimate = 'recorded '; $lang->action->label->editestimate = 'edited '; $lang->action->label->canceled = 'cancelled '; $lang->action->label->finished = 'finished '; @@ -459,6 +461,7 @@ $lang->action->dynamicAction->task['confirmed'] = 'Xác nhận nhiệ $lang->action->dynamicAction->task['started'] = 'Bắt đầu nhiệm vụ'; $lang->action->dynamicAction->task['finished'] = 'Nhiệm vụ hoàn thành'; $lang->action->dynamicAction->task['recordworkhour'] = 'Thêm dự tính'; +$lang->action->dynamicAction->task['recordestimate'] = 'Thêm dự tính'; $lang->action->dynamicAction->task['editestimate'] = 'Sửa dự tính'; $lang->action->dynamicAction->task['deleteestimate'] = 'Xóa dự tính'; $lang->action->dynamicAction->task['paused'] = 'Pause nhiệm vụ'; @@ -704,6 +707,7 @@ $lang->action->search->label['unlinkedfromexecution'] = $lang->action->label->un $lang->action->search->label['started'] = $lang->action->label->started; $lang->action->search->label['restarted'] = $lang->action->label->restarted; $lang->action->search->label['recordworkhour'] = $lang->action->label->recordworkhour; +$lang->action->search->label['recordestimate'] = $lang->action->label->recordworkhour; $lang->action->search->label['editestimate'] = $lang->action->label->editestimate; $lang->action->search->label['canceled'] = $lang->action->label->canceled; $lang->action->search->label['finished'] = $lang->action->label->finished; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 6a845ad0a2..04eb9689d4 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -202,6 +202,7 @@ $lang->action->desc->restarted = '$date, 由 $actor $lang->action->desc->delayed = '$date, 由 $actor 延期。' . "\n"; $lang->action->desc->suspended = '$date, 由 $actor 挂起。' . "\n"; $lang->action->desc->recordworkhour = '$date, 由 $actor 记录工时,消耗 $extra 小时。'; +$lang->action->desc->recordestimate = '$date, 由 $actor 记录工时,消耗 $extra 小时。'; $lang->action->desc->editestimate = '$date, 由 $actor 编辑工时。'; $lang->action->desc->deleteestimate = '$date, 由 $actor 删除工时。'; $lang->action->desc->canceled = '$date, 由 $actor 取消。' . "\n"; @@ -398,6 +399,7 @@ $lang->action->label->unlinkchildstory = "移除了细分{$lang->SRCommon $lang->action->label->started = '开始了'; $lang->action->label->restarted = '继续了'; $lang->action->label->recordworkhour = '记录了工时'; +$lang->action->label->recordestimate = '记录了工时'; $lang->action->label->editestimate = '编辑了工时'; $lang->action->label->canceled = '取消了'; $lang->action->label->finished = '完成了'; @@ -644,6 +646,7 @@ $lang->action->dynamicAction->task['confirmed'] = "确认{$lang->SRCo $lang->action->dynamicAction->task['started'] = '开始任务'; $lang->action->dynamicAction->task['finished'] = '完成任务'; $lang->action->dynamicAction->task['recordworkhour'] = '记录工时'; +$lang->action->dynamicAction->task['recordestimate '] = '记录工时'; $lang->action->dynamicAction->task['editestimate'] = '编辑工时'; $lang->action->dynamicAction->task['deleteestimate'] = '删除工时'; $lang->action->dynamicAction->task['paused'] = '暂停任务'; @@ -921,6 +924,7 @@ $lang->action->search->label['linked2kanban'] = $lang->action->label->li $lang->action->search->label['started'] = $lang->action->label->started; $lang->action->search->label['restarted'] = $lang->action->label->restarted; $lang->action->search->label['recordworkhour'] = $lang->action->label->recordworkhour; +$lang->action->search->label['recordestimate '] = $lang->action->label->recordworkhour; $lang->action->search->label['editestimate'] = $lang->action->label->editestimate; $lang->action->search->label['canceled'] = $lang->action->label->canceled; $lang->action->search->label['finished'] = $lang->action->label->finished; @@ -956,6 +960,7 @@ $lang->action->apiTitle->restarted = '继续。'; $lang->action->apiTitle->delayed = '执行了延期操作。'; $lang->action->apiTitle->suspended = '挂起。'; $lang->action->apiTitle->recordworkhour = '记录工时,消耗 %s 小时。'; +$lang->action->apiTitle->recordestimate = '记录工时,消耗 %s 小时。'; $lang->action->apiTitle->editestimate = '编辑了工时。'; $lang->action->apiTitle->deleteestimate = '删除工时。'; $lang->action->apiTitle->canceled = '执行取消操作。'; diff --git a/module/task/css/common.ui.css b/module/task/css/common.ui.css index 68c23dbf64..7ce4e16f9d 100644 --- a/module/task/css/common.ui.css +++ b/module/task/css/common.ui.css @@ -13,5 +13,3 @@ div.no-background .input-group-addon {background: none;} #teamTable tr:nth-last-child(2) td:first-child .icon {display: none;} #teamTable td.required {position: relative;} #teamTable td.required:after {content: '*'; color: rgba(var(--color-danger-500-rgb),var(--tw-text-opacity)); position: absolute; top: 1rem; right: 0.125rem;} - -:root {--modal-base: 45rem;} diff --git a/module/task/ui/create.html.php b/module/task/ui/create.html.php index 93e5389a1e..6f73350ba6 100644 --- a/module/task/ui/create.html.php +++ b/module/task/ui/create.html.php @@ -219,6 +219,48 @@ formPanel setID('taskCreateForm'), set::title($lang->task->create), $from == 'task' ? set::customFields(true) : null, + modal + ( + set::id('modalTeam'), + set::title($lang->task->teamMember), + h::table + ( + set::id('teamTable'), + h::tr + ( + h::td + ( + width('90px'), + $lang->task->mode + ), + h::td + ( + picker + ( + set::name("mode"), + set::value("linear"), + set::items($lang->task->modeList), + set::required(true) + ) + ) + ), + setClass('table table-form'), + $teamForm, + h::tr + ( + h::td + ( + setClass('team-saveBtn'), + set(array('colspan' => 4)), + btn + ( + setClass('toolbar-item btn primary'), + $lang->save + ) + ) + ) + ) + ), formRow ( $executionBox, @@ -507,52 +549,4 @@ formPanel ) ), $afterRow, - modalTrigger - ( - modal - ( - setID('modalTeam'), - set::title($lang->task->teamMember), - h::table - ( - setID('teamTable'), - h::tr - ( - h::td - ( - width('90px'), - $lang->task->mode - ), - h::td - ( - picker - ( - set::name("mode"), - set::value("linear"), - set::items($lang->task->modeList), - set::required(true) - ) - ) - ), - setClass('table table-form'), - $teamForm, - h::tr - ( - h::td - ( - setClass('team-saveBtn'), - set(array('colspan' => 4)), - btn - ( - setClass('toolbar-item btn primary'), - $lang->save - ) - ) - ) - ) - ) - ) ); - -/* ====== Render page ====== */ -render(); From c3902bb50e6c6735429725b0dd7beb78a7cf18e0 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 15:30:45 +0800 Subject: [PATCH 063/235] * Set object id to history in release::view. --- module/release/ui/view.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/release/ui/view.html.php b/module/release/ui/view.html.php index e456afa53a..c0cda23c85 100644 --- a/module/release/ui/view.html.php +++ b/module/release/ui/view.html.php @@ -270,7 +270,7 @@ detailBody set::files($release->files) ), h::hr(set::className('mt-6')), - history() + history(set::objectID($release->id)) ) ) ) From 91062ce797e01eafd3b0b992d383e5b0b8ee7a67 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 15:31:33 +0800 Subject: [PATCH 064/235] * Add the limit of the multiple task assign to. --- module/task/ui/assignto.html.php | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/module/task/ui/assignto.html.php b/module/task/ui/assignto.html.php index d60392e17b..c3cb5dcd7b 100644 --- a/module/task/ui/assignto.html.php +++ b/module/task/ui/assignto.html.php @@ -13,6 +13,31 @@ declare(strict_types=1); namespace zin; /* zin: Define the form in main content */ +if(!empty($task->members) && strpos('wait,doing,pause', $task->status) !== false && (!isset($task->members[$app->user->account]) || $task->mode == 'linear')) +{ + $notice = ''; + if($task->mode == 'linear') + { + $notice = $lang->task->transferNotice; + } + else + { + $notice = html(sprintf($lang->task->deniedNotice, '' . $lang->task->teamMember . '', $lang->task->transfer)); + } + + div + ( + setClass('alert with-icon my-8'), + icon('exclamation-sign text-gray text-4xl'), + div + ( + setClass('content'), + $notice + ) + ); +} +else +{ modalHeader ( set::title($lang->task->assignAction), @@ -56,6 +81,10 @@ formPanel ) ); hr(); -history(); +history +( + set::objectID($task->id) +); +} render(); From d606799f4cfb6f03837404315ce201b3b249754a Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 16 Nov 2023 15:32:40 +0800 Subject: [PATCH 065/235] * Implement style with class. --- module/task/css/manageteam.ui.css | 1 - module/task/css/recordworkhour.ui.css | 1 - module/task/ui/manageteam.html.php | 2 +- module/task/ui/recordworkhour.html.php | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/module/task/css/manageteam.ui.css b/module/task/css/manageteam.ui.css index 7deff58a16..373ae8fd8c 100644 --- a/module/task/css/manageteam.ui.css +++ b/module/task/css/manageteam.ui.css @@ -1,2 +1 @@ -div.alert > .icon {font-size: 42px;} #teamTable.table tr {border: none;} diff --git a/module/task/css/recordworkhour.ui.css b/module/task/css/recordworkhour.ui.css index 8b9cdb28b5..00e18c9f08 100644 --- a/module/task/css/recordworkhour.ui.css +++ b/module/task/css/recordworkhour.ui.css @@ -3,4 +3,3 @@ .panel-form .panel-heading {padding: 1.5rem 0} .panel-form .panel-heading .panel-title {font-size: 14px} .panel-form .panel-body {padding: 0 0 1rem 0} -div.alert > .icon {font-size: 42px;} diff --git a/module/task/ui/manageteam.html.php b/module/task/ui/manageteam.html.php index f341f9b8c2..c578a79ac3 100644 --- a/module/task/ui/manageteam.html.php +++ b/module/task/ui/manageteam.html.php @@ -14,7 +14,7 @@ if(!isset($task->members[$app->user->account])) div ( setClass('alert with-icon my-8'), - icon('exclamation-sign text-gray'), + icon('exclamation-sign text-gray text-4xl'), div ( setClass('content'), diff --git a/module/task/ui/recordworkhour.html.php b/module/task/ui/recordworkhour.html.php index 07b95ccb6b..10610e2fd9 100644 --- a/module/task/ui/recordworkhour.html.php +++ b/module/task/ui/recordworkhour.html.php @@ -151,7 +151,7 @@ if(!$this->task->canOperateEffort($task)) div ( setClass('alert with-icon'), - icon('exclamation-sign text-gray'), + icon('exclamation-sign text-gray text-4xl'), div ( setClass('content'), From f7222ed32853a3d6982a95c3c5b477ecb0493118 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 15:36:13 +0800 Subject: [PATCH 066/235] - project: remove unused lang item. --- module/project/lang/de.php | 15 +++++++-------- module/project/lang/en.php | 15 +++++++-------- module/project/lang/fr.php | 15 +++++++-------- module/project/lang/zh-cn.php | 15 +++++++-------- module/project/ui/create.html.php | 3 +-- module/project/ui/edit.html.php | 3 +-- 6 files changed, 30 insertions(+), 36 deletions(-) diff --git a/module/project/lang/de.php b/module/project/lang/de.php index bac30c54b4..1b6c0b5fed 100644 --- a/module/project/lang/de.php +++ b/module/project/lang/de.php @@ -458,14 +458,13 @@ $lang->project->moreSelects = array(); $lang->project->moreSelects['suspended'] = 'Suspended'; $lang->project->moreSelects['closed'] = 'Closed'; -$lang->project->manDay = 'Man Day'; -$lang->project->day = 'Day'; -$lang->project->newProduct = 'New Product'; -$lang->project->associatePlan = 'Associate Plan'; -$lang->project->editorPlaceholder = 'You can directly paste images in the editor. Hotkeys: Command C+V'; -$lang->project->tenThousandYuan = '10k'; -$lang->project->planDate = 'Schedule Date'; -$lang->project->delayInfo = 'Delayed for %s days'; +$lang->project->manDay = 'Man Day'; +$lang->project->day = 'Day'; +$lang->project->newProduct = 'New Product'; +$lang->project->associatePlan = 'Associate Plan'; +$lang->project->tenThousandYuan = '10k'; +$lang->project->planDate = 'Schedule Date'; +$lang->project->delayInfo = 'Delayed for %s days'; $lang->project->executionList['scrum'] = $lang->projectCommon . ' Sprint'; $lang->project->executionList['waterfall'] = $lang->projectCommon . ' Stage'; diff --git a/module/project/lang/en.php b/module/project/lang/en.php index 063f79c55c..243cc4f6ac 100644 --- a/module/project/lang/en.php +++ b/module/project/lang/en.php @@ -462,14 +462,13 @@ $lang->project->moreSelects = array(); $lang->project->moreSelects['suspended'] = 'Suspended'; $lang->project->moreSelects['closed'] = 'Closed'; -$lang->project->manDay = 'Man Day'; -$lang->project->day = 'Day'; -$lang->project->newProduct = 'New Product'; -$lang->project->associatePlan = 'Associate Plan'; -$lang->project->editorPlaceholder = 'You can directly paste images in the editor. Hotkeys: Command C+V'; -$lang->project->tenThousandYuan = '10k'; -$lang->project->planDate = 'Schedule Date'; -$lang->project->delayInfo = 'Delayed for %s days'; +$lang->project->manDay = 'Man Day'; +$lang->project->day = 'Day'; +$lang->project->newProduct = 'New Product'; +$lang->project->associatePlan = 'Associate Plan'; +$lang->project->tenThousandYuan = '10k'; +$lang->project->planDate = 'Schedule Date'; +$lang->project->delayInfo = 'Delayed for %s days'; $lang->project->executionList['scrum'] = $lang->projectCommon . ' Sprint'; $lang->project->executionList['waterfall'] = $lang->projectCommon . ' Stage'; diff --git a/module/project/lang/fr.php b/module/project/lang/fr.php index bac30c54b4..1b6c0b5fed 100644 --- a/module/project/lang/fr.php +++ b/module/project/lang/fr.php @@ -458,14 +458,13 @@ $lang->project->moreSelects = array(); $lang->project->moreSelects['suspended'] = 'Suspended'; $lang->project->moreSelects['closed'] = 'Closed'; -$lang->project->manDay = 'Man Day'; -$lang->project->day = 'Day'; -$lang->project->newProduct = 'New Product'; -$lang->project->associatePlan = 'Associate Plan'; -$lang->project->editorPlaceholder = 'You can directly paste images in the editor. Hotkeys: Command C+V'; -$lang->project->tenThousandYuan = '10k'; -$lang->project->planDate = 'Schedule Date'; -$lang->project->delayInfo = 'Delayed for %s days'; +$lang->project->manDay = 'Man Day'; +$lang->project->day = 'Day'; +$lang->project->newProduct = 'New Product'; +$lang->project->associatePlan = 'Associate Plan'; +$lang->project->tenThousandYuan = '10k'; +$lang->project->planDate = 'Schedule Date'; +$lang->project->delayInfo = 'Delayed for %s days'; $lang->project->executionList['scrum'] = $lang->projectCommon . ' Sprint'; $lang->project->executionList['waterfall'] = $lang->projectCommon . ' Stage'; diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php index 93ea88d455..4a3ff7b05d 100644 --- a/module/project/lang/zh-cn.php +++ b/module/project/lang/zh-cn.php @@ -462,14 +462,13 @@ $lang->project->moreSelects = array(); $lang->project->moreSelects['suspended'] = '已挂起'; $lang->project->moreSelects['closed'] = '已关闭'; -$lang->project->manDay = '人天'; -$lang->project->day = '天'; -$lang->project->newProduct = '新产品'; -$lang->project->associatePlan = '关联计划'; -$lang->project->editorPlaceholder = '可以在编辑器直接贴图。快捷键:Command C+V'; -$lang->project->tenThousandYuan = '万元'; -$lang->project->planDate = '计划日期'; -$lang->project->delayInfo = '延期 %s 天'; +$lang->project->manDay = '人天'; +$lang->project->day = '天'; +$lang->project->newProduct = '新产品'; +$lang->project->associatePlan = '关联计划'; +$lang->project->tenThousandYuan = '万元'; +$lang->project->planDate = '计划日期'; +$lang->project->delayInfo = '延期 %s 天'; $lang->project->executionList['scrum'] = $lang->projectCommon . '迭代'; $lang->project->executionList['waterfall'] = $lang->projectCommon . '阶段'; diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 390f83f0da..9233e615e8 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -504,8 +504,7 @@ formPanel ( set::name('desc'), set::label($lang->project->desc), - set::control('editor'), - set::placeholder($lang->project->editorPlaceholder) + set::control('editor') ), formRow ( diff --git a/module/project/ui/edit.html.php b/module/project/ui/edit.html.php index 49df563330..5df38fefb6 100644 --- a/module/project/ui/edit.html.php +++ b/module/project/ui/edit.html.php @@ -479,8 +479,7 @@ formPanel editor ( set::name('desc'), - html($project->desc), - set::placeholder($lang->project->editorPlaceholder) + html($project->desc) ) ), formRow From 609ae3db841a9e489cf258af7958f869f1615816 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 16 Nov 2023 15:46:47 +0800 Subject: [PATCH 067/235] * Fix the bug of doc search. --- module/api/control.php | 2 +- module/doc/control.php | 2 +- module/doc/ui/createbutton.html.php | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/module/api/control.php b/module/api/control.php index 2d87abf051..a45279bcef 100755 --- a/module/api/control.php +++ b/module/api/control.php @@ -144,7 +144,7 @@ class api extends control $this->view->objectID = $objectID; $this->view->moduleID = $moduleID; $this->view->version = $version; - $this->view->libTree = $this->doc->getLibTree($libID, $libs, 'api', $moduleID, $objectID, $browseType, $param); + $this->view->libTree = $this->doc->getLibTree($libID, $libs, 'api', $moduleID, $objectID, $browseType, (int)$param); $this->view->users = $this->user->getPairs('noclosed,noletter'); $this->view->objectDropdown = isset($libs[$libID]) ? $this->generateLibsDropMenu($libs[$libID], $release) : ''; $this->view->spaceType = 'api'; diff --git a/module/doc/control.php b/module/doc/control.php index b2d11625e6..5ba12673e9 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -1270,7 +1270,7 @@ class doc extends control $this->view->isFirstLoad = $isFirstLoad; $this->view->param = $queryID; $this->view->users = $this->user->getPairs('noletter'); - $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $moduleID, $objectID, $browseType, $param); + $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $moduleID, $objectID, $browseType, (int)$param); $this->view->libID = $libID; $this->view->moduleID = $moduleID; $this->view->objectDropdown = $objectDropdown; diff --git a/module/doc/ui/createbutton.html.php b/module/doc/ui/createbutton.html.php index 57044545b8..e3e190c780 100644 --- a/module/doc/ui/createbutton.html.php +++ b/module/doc/ui/createbutton.html.php @@ -12,14 +12,14 @@ namespace zin; $createButton = $emptyCreateBtn = null; $typeID = empty($lib) ? $objectID : zget($lib, (string)$lib->type, 0); -$libType = empty($lib) ? '' : $lib->type; +$createType = empty($lib) ? '' : $lib->type; $templateParam = $this->config->edition == 'max' ? '&from=template' : ''; $buttonItems = array(); foreach($lang->doc->createList as $typeKey => $typeName) { $docType = zget($config->doc->iconList, $typeKey); - $params = "objectType={$libType}&objectID={$typeID}&libID={$libID}&moduleID={$moduleID}&type={$typeKey}"; - if($typeKey == 'template' and $config->edition == 'max') $params = "objectType={$libType}&objectID={$typeID}&libID={$libID}&moduleID={$moduleID}&type=html&from=template"; + $params = "objectType={$createType}&objectID={$typeID}&libID={$libID}&moduleID={$moduleID}&type={$typeKey}"; + if($typeKey == 'template' and $config->edition == 'max') $params = "objectType={$createType}&objectID={$typeID}&libID={$libID}&moduleID={$moduleID}&type=html&from=template"; $buttonItems[] = array ( From ffc49061bd454dac0c8a70780c55e0618249c9aa Mon Sep 17 00:00:00 2001 From: wangyidong Date: Thu, 16 Nov 2023 15:48:51 +0800 Subject: [PATCH 068/235] * Adjust for kanban action. --- module/bug/js/common.ui.js | 12 +- module/bug/lang/de.php | 6 +- module/bug/lang/en.php | 6 +- module/bug/lang/fr.php | 6 +- module/bug/lang/zh-cn.php | 6 +- module/bug/ui/batchcreate.html.php | 206 ++++--------------------- module/bug/ui/create.html.php | 6 +- module/bug/zen.php | 4 +- module/execution/control.php | 22 +-- module/execution/js/linkstory.ui.js | 7 +- module/execution/ui/importbug.html.php | 34 ++-- module/execution/ui/linkstory.html.php | 41 +++-- module/file/js/uploadimages.ui.js | 26 +++- module/kanban/model.php | 34 ++-- 14 files changed, 149 insertions(+), 267 deletions(-) diff --git a/module/bug/js/common.ui.js b/module/bug/js/common.ui.js index 774a2dfd04..cc32d2d2ad 100644 --- a/module/bug/js/common.ui.js +++ b/module/bug/js/common.ui.js @@ -695,8 +695,7 @@ function loadBuildActions() { if(config.currentMethod == 'edit') return; $('#buildBoxActions').empty().hide(); - let itemCount = $('#openedBuild').find('option').length; - if($('#openedBuild').attr('data-items') != undefined) itemCount = $('#openedBuild').attr('data-items'); + let itemCount = $('[name^=openedBuild]').zui('picker').options.items.length; if(itemCount <= 1) { let html = ''; @@ -712,8 +711,8 @@ function loadBuildActions() let link = $.createLink('release', 'create', 'productID=' + productID + '&branch=' + branch); if(projectID > 0) link = $.createLink('projectrelease', 'create', 'projectID=' + projectID); - html += '' + createRelease + ' '; - html += '' + refresh + ''; + html += '' + createRelease + ' '; + html += '' + refresh + ''; } else { @@ -721,9 +720,8 @@ function loadBuildActions() const productID = $('[name="product"]').val(); const projectID = $('[name="project"]').val(); let link = $.createLink('build', 'create','executionID=' + executionID + '&productID=' + productID + '&projectID=' + projectID); - link += link.indexOf('?') >= 0 ? '&onlybody=yes' : '?onlybody=yes'; - html += '' + createBuild + ' '; - html += '' + refresh + ''; + html += '' + createBuild + ' '; + html += '' + refresh + ''; } $('#buildBoxActions').html(html).show(); } diff --git a/module/bug/lang/de.php b/module/bug/lang/de.php index 69a4bdd93d..9792c59cc4 100644 --- a/module/bug/lang/de.php +++ b/module/bug/lang/de.php @@ -198,9 +198,9 @@ $lang->bug->legendRelated = 'Sonstige Infos'; $lang->bug->legendThisWeekCreated = 'This Week Created'; /* Template. */ -$lang->bug->tplStep = "

[Steps]


"; -$lang->bug->tplResult = "

[Results]


"; -$lang->bug->tplExpect = "

[Expectations]


"; +$lang->bug->tplStep = "

[Steps]

"; +$lang->bug->tplResult = "

[Results]

"; +$lang->bug->tplExpect = "

[Expectations]

"; /* Value list for each field. */ $lang->bug->severityList[0] = ''; diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index 3876ff6225..5e02238215 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -198,9 +198,9 @@ $lang->bug->legendRelated = 'Related Info'; $lang->bug->legendThisWeekCreated = 'This Week Created'; /* Template. */ -$lang->bug->tplStep = "

[Steps]


"; -$lang->bug->tplResult = "

[Results]


"; -$lang->bug->tplExpect = "

[Expectations]


"; +$lang->bug->tplStep = "

[Steps]

"; +$lang->bug->tplResult = "

[Results]

"; +$lang->bug->tplExpect = "

[Expectations]

"; /* Value list for each field. */ $lang->bug->severityList[0] = ''; diff --git a/module/bug/lang/fr.php b/module/bug/lang/fr.php index 2fa24512ef..a3580e765e 100644 --- a/module/bug/lang/fr.php +++ b/module/bug/lang/fr.php @@ -198,9 +198,9 @@ $lang->bug->legendRelated = 'Infos connexes'; $lang->bug->legendThisWeekCreated = 'This Week Created'; /* Template. */ -$lang->bug->tplStep = "

[Etape]


"; -$lang->bug->tplResult = "

[Résultats]


"; -$lang->bug->tplExpect = "

[Résultats attendus]


"; +$lang->bug->tplStep = "

[Etape]

"; +$lang->bug->tplResult = "

[Résultats]

"; +$lang->bug->tplExpect = "

[Résultats attendus]

"; /* Value list for each field. */ $lang->bug->severityList[0] = ''; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 55b030afa8..b1455f18b2 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -198,9 +198,9 @@ $lang->bug->legendRelated = '其他信息'; $lang->bug->legendThisWeekCreated = '本周新增'; /* 模板。*/ -$lang->bug->tplStep = "

[步骤]


"; -$lang->bug->tplResult = "

[结果]


"; -$lang->bug->tplExpect = "

[期望]


"; +$lang->bug->tplStep = "

[步骤]

"; +$lang->bug->tplResult = "

[结果]

"; +$lang->bug->tplExpect = "

[期望]

"; /* 各个字段取值列表。*/ $lang->bug->severityList[0] = ''; diff --git a/module/bug/ui/batchcreate.html.php b/module/bug/ui/batchcreate.html.php index 2e0beaaee8..5286ae6a57 100644 --- a/module/bug/ui/batchcreate.html.php +++ b/module/bug/ui/batchcreate.html.php @@ -10,79 +10,48 @@ declare(strict_types=1); */ namespace zin; -$visibleFields = array(); -$requiredFields = array(); -foreach(explode(',', $showFields) as $field) +$defaultBug = array('module' => $moduleID, 'project' => $projectID, 'execution' => $executionID, 'openedBuild' => 'trunk', 'pri' => 3, 'severity' => 3); +if($product->type != 'normal') $defaultBug['branch'] = $branch; +if(isset($executionType) && $executionType == 'kanban') { - if($field) $visibleFields[$field] = ''; + $defaultBug['region'] = $regionID; + $defaultBug['laneID'] = $laneID; } -foreach(explode(',', $config->bug->create->requiredFields) as $field) +$bugs = array(); +if($titles) { - if($field) + foreach($titles as $title => $fileName) { - $requiredFields[$field] = ''; - if(strpos(",{$config->bug->list->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; + $bug = $defaultBug; + $bug['title'] = $title; + $bug['uploadImage'] = $fileName; + $bugs[] = $bug; } } +foreach(array_filter(explode(',', $config->bug->create->requiredFields)) as $field) $requiredFields[$field] = ''; + $items = array(); /* Field of id. */ -$items[] = array -( - 'name' => 'id', - 'label' => $lang->idAB, - 'control' => 'index', - 'width' => '32px' -); +$items[] = array('name' => 'id', 'label' => $lang->idAB, 'control' => 'index', 'width' => '32px'); +if($bugs) $items[] = array('name' => 'uploadImage', 'label' => '', 'control' => 'hidden', 'hidden' => true); /* Field of branch. */ -$items[] = array -( - 'name' => 'branch', - 'label' => $lang->product->branchName[$product->type], - 'hidden' => zget($visibleFields, $product->type, true, false), - 'control' => 'picker', - 'items' => $branches, - 'value' => $branch, - 'width' => '200px', - 'ditto' => true -); +if($product->type != 'normal') $items[] = array('name' => 'branch', 'label' => $lang->product->branchName[$product->type], 'control' => 'picker', 'items' => $branches, 'value' => $branch, 'width' => '200px', 'ditto' => true); /* Field of module. */ -$items[] = array -( - 'name' => 'module', - 'label' => $lang->bug->module, - 'control' => 'picker', - 'items' => $moduleOptionMenu, - 'value' => $moduleID, - 'width' => '200px', - 'required' => isset($requiredFields['module']), - 'ditto' => true -); +$items[] = array('name' => 'module', 'label' => $lang->bug->module, 'control' => 'picker', 'items' => $moduleOptionMenu, 'value' => $moduleID, 'width' => '200px', 'required' => isset($requiredFields['module']), 'ditto' => true); /* Field of project. */ -$items[] = array -( - 'name' => 'project', - 'label' => $lang->bug->project, - 'hidden' => zget($visibleFields, 'project', true, false), - 'control' => 'picker', - 'items' => $projects, - 'value' => $projectID, - 'width' => '200px', - 'required' => isset($requiredFields['project']), - 'ditto' => true -); +$items[] = array('name' => 'project', 'label' => $lang->bug->project, 'control' => 'picker', 'items' => $projects, 'value' => $projectID, 'width' => '200px', 'required' => isset($requiredFields['project']), 'ditto' => true); /* Field of execution. */ $items[] = array ( 'name' => 'execution', 'label' => isset($project->model) && $project->model == 'kanban' ? $lang->bug->kanban : $lang->bug->execution, - 'hidden' => zget($visibleFields, 'execution', true, false), 'control' => 'picker', 'items' => $executions, 'value' => $executionID, @@ -92,158 +61,49 @@ $items[] = array ); /* Field of openedBuild. */ -$items[] = array -( - 'name' => 'openedBuild', - 'label' => $lang->bug->openedBuild, - 'control' => 'picker', - 'items' => $builds, - 'value' => 'trunk', - 'multiple' => true, - 'width' => '200px', - 'required' => true, - 'ditto' => true -); +$items[] = array('name' => 'openedBuild', 'label' => $lang->bug->openedBuild, 'control' => 'picker', 'items' => $builds, 'value' => 'trunk', 'multiple' => true, 'width' => '200px', 'required' => true, 'ditto' => true); /* Field of title. */ -$items[] = array -( - 'name' => 'title', - 'label' => $lang->bug->title, - 'width' => '240px', - 'required' => true -); +$items[] = array( 'name' => 'title', 'label' => $lang->bug->title, 'width' => '240px', 'required' => true); /* Field of region and lane. */ if(isset($executionType) && $executionType == 'kanban') { - $items[] = array - ( - 'name' => 'region', - 'label' => $lang->kanbancard->region, - 'control' => 'picker', - 'value' => $regionID, - 'items' => $regionPairs, - 'width' => '200px', - 'required' => true - ); - - $items[] = array - ( - 'name' => 'laneID', - 'label' => $lang->kanbancard->lane, - 'control' => 'picker', - 'value' => $laneID, - 'items' => $lanePairs, - 'width' => '200px', - 'required' => true - ); + $items[] = array('name' => 'region', 'label' => $lang->kanbancard->region, 'control' => 'picker', 'value' => $regionID, 'items' => $regionPairs, 'width' => '200px', 'required' => true); + $items[] = array('name' => 'laneID', 'label' => $lang->kanbancard->lane, 'control' => 'picker', 'value' => $laneID, 'items' => $lanePairs, 'width' => '200px', 'required' => true); } /* Field of deadline. */ -$items[] = array -( - 'name' => 'deadline', - 'label' => $lang->bug->deadline, - 'hidden' => zget($visibleFields, 'deadline', true, false), - 'control' => 'date', - 'width' => '136px', - 'required' => isset($requiredFields['deadline']), - 'ditto' => true -); +$items[] = array('name' => 'deadline', 'label' => $lang->bug->deadline, 'control' => 'date', 'width' => '136px', 'required' => isset($requiredFields['deadline']), 'ditto' => true); /* Field of steps. */ -$items[] = array -( - 'name' => 'steps', - 'label' => $lang->bug->steps, - 'hidden' => zget($visibleFields, 'steps', true, false), - 'width' => '240px', - 'required' => isset($requiredFields['steps']) -); +$items[] = array('name' => 'steps', 'label' => $lang->bug->steps, 'width' => '240px', 'required' => isset($requiredFields['steps'])); /* Field of type. */ -$items[] = array -( - 'name' => 'type', - 'label' => $lang->typeAB, - 'hidden' => zget($visibleFields, 'type', true, false), - 'control' => 'picker', - 'items' => $lang->bug->typeList, - 'value' => '', - 'width' => '160px', - 'required' => isset($requiredFields['type']), - 'ditto' => true -); +$items[] = array('name' => 'type', 'label' => $lang->typeAB, 'control' => 'picker', 'items' => $lang->bug->typeList, 'value' => '', 'width' => '160px', 'required' => isset($requiredFields['type']), 'ditto' => true); /* Field of pri. */ -$items[] = array -( - 'name' => 'pri', - 'label' => $lang->bug->pri, - 'hidden' => zget($visibleFields, 'pri', true, false), - 'control' => 'priPicker', - 'items' => $lang->bug->priList, - 'value' => 3, - 'width' => '100px', - 'required' => isset($requiredFields['pri']), - 'ditto' => true -); +$items[] = array('name' => 'pri', 'label' => $lang->bug->pri, 'control' => 'priPicker', 'items' => $lang->bug->priList, 'value' => 3, 'width' => '100px', 'required' => isset($requiredFields['pri']), 'ditto' => true); /* Field of severity. */ -$items[] = array -( - 'name' => 'severity', - 'label' => $lang->bug->severity, - 'hidden' => zget($visibleFields, 'severity', true, false), - 'control' => 'severityPicker', - 'items' => $lang->bug->severityList, - 'value' => 3, - 'width' => '80px', - 'required' => isset($requiredFields['severity']) -); +$items[] = array('name' => 'severity', 'label' => $lang->bug->severity, 'control' => 'severityPicker', 'items' => $lang->bug->severityList, 'value' => 3, 'width' => '80px', 'required' => isset($requiredFields['severity'])); /* Field of os. */ -$items[] = array -( - 'name' => 'os', - 'label' => $lang->bug->os, - 'hidden' => zget($visibleFields, 'os', true, false), - 'control' => 'picker', - 'items' => $lang->bug->osList, - 'width' => '200px', - 'multiple' => true, - 'required' => isset($requiredFields['os']) -); +$items[] = array('name' => 'os', 'label' => $lang->bug->os, 'control' => 'picker', 'items' => $lang->bug->osList, 'width' => '200px', 'multiple' => true, 'required' => isset($requiredFields['os'])); /* Field of browser. */ -$items[] = array -( - 'name' => 'browser', - 'label' => $lang->bug->browser, - 'hidden' => zget($visibleFields, 'browser', true, false), - 'control' => 'picker', - 'items' => $lang->bug->browserList, - 'width' => '200px', - 'multiple' => true, - 'required' => isset($requiredFields['browser']) -); +$items[] = array('name' => 'browser', 'label' => $lang->bug->browser, 'control' => 'picker', 'items' => $lang->bug->browserList, 'width' => '200px', 'multiple' => true, 'required' => isset($requiredFields['browser'])); /* Field of keywords. */ -$items[] = array -( - 'name' => 'keywords', - 'label' => $lang->bug->keywords, - 'hidden' => zget($visibleFields, 'keywords', true, false), - 'width' => '200px', - 'required' => isset($requiredFields['keywords']) -); +$items[] = array('name' => 'keywords', 'label' => $lang->bug->keywords, 'width' => '200px', 'required' => isset($requiredFields['keywords'])); formBatchPanel ( set::title($lang->bug->batchCreate), set::uploadParams('module=bug¶ms=' . helper::safe64Encode("productID=$product->id&branch=$branch&executionID=$executionID&moduleID=$moduleID")), + set::customFields(array('list' => $customFields, 'show' => explode(',', $showFields), 'key' => 'batchCreateFields')), set::pasteField('title'), + $bugs ? set::data($bugs) : null, set::items($items), on::change('[data-name="branch"]', 'setBranchRelated'), on::change('[data-name="project"]', 'loadProductExecutionsByProject'), diff --git a/module/bug/ui/create.html.php b/module/bug/ui/create.html.php index d431431d33..9fb1cd4b3a 100644 --- a/module/bug/ui/create.html.php +++ b/module/bug/ui/create.html.php @@ -154,9 +154,10 @@ formPanel ), span ( - set('class', 'input-group-addon'), + set('class', 'input-group-btn'), a ( + setClass('btn'), set('id', 'allBuilds'), set('href', 'javascript:;'), $lang->bug->loadAll @@ -178,9 +179,10 @@ formPanel ), span ( - set('class', 'input-group-addon'), + set('class', 'input-group-btn'), a ( + setClass('btn'), set('id', 'allUsers'), set('href', 'javascript:;'), $lang->bug->loadAll diff --git a/module/bug/zen.php b/module/bug/zen.php index fa876beb36..27f9e16859 100644 --- a/module/bug/zen.php +++ b/module/bug/zen.php @@ -1768,7 +1768,7 @@ class bugZen extends bug * @access protected * @return array */ - protected function processImageForBatchCreate(object $bug, string $uploadImage, array $bugImagesFiles): array + protected function processImageForBatchCreate(object $bug, string|null $uploadImage, array $bugImagesFiles): array { /* When the bug is created by uploading an image, add the image to the step of the bug. */ if(!empty($uploadImage)) @@ -1986,7 +1986,7 @@ class bugZen extends bug * @access protected * @return bool */ - protected function afterBatchCreate(object $bug, array $output, string $uploadImage, array $file): bool + protected function afterBatchCreate(object $bug, array $output, string|null $uploadImage, array $file): bool { /* If bug has the execution, update kanban data. */ if($bug->execution) diff --git a/module/execution/control.php b/module/execution/control.php index 6253801ed1..e086f875b3 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -362,7 +362,7 @@ class execution extends control $this->execution->importBug($tasks); if(dao::isError()) return $this->sendError(dao::getError()); - return $this->sendSuccess(array('load' => true)); + return $this->sendSuccess(array('load' => true, 'closeModal' => true)); } $this->execution->setMenu($executionID); @@ -2162,23 +2162,15 @@ class execution extends control if($object->type != 'project' and $object->project != 0) $this->execution->linkStory($object->project, $this->post->stories ? $this->post->stories : array()); $this->execution->linkStory($objectID, $this->post->stories ? $this->post->stories : array(), $extra); - if(!isInModal()) return $this->sendSuccess(array('load' => $browseLink)); - if(!$this->app->tab !== 'execution') return $this->sendSuccess(array('closeModal' => true, 'locate' => $browseLink)); - - $execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all'; - $execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default'; - if($object->type == 'kanban') + if(isInModal()) { - $kanbanData = $this->loadModel('kanban')->getRDKanban($objectID, $execLaneType, 'id_desc', 0, $execGroupBy); - $kanbanData = json_encode($kanbanData); - return $this->sendSuccess(array('closeModal' => true, 'load' => true, 'callback' => "parent.updateKanban($kanbanData)")); + $execLaneType = $this->session->execLaneType ? $this->session->execLaneType : 'all'; + $execGroupBy = $this->session->execGroupBy ? $this->session->execGroupBy : 'default'; + if($object->type == 'kanban') return $this->sendSuccess(array('closeModal' => true, 'load' => true, 'callback' => "refreshKanban()")); + return $this->sendSuccess(array('closeModal' => true, 'load' => true, 'callback' => "refreshKanban()")); } - $kanbanData = $this->loadModel('kanban')->getExecutionKanban($objectID, $execLaneType, $execGroupBy); - $kanbanType = $execLaneType == 'all' ? 'story' : key($kanbanData); - $kanbanData = $kanbanData[$kanbanType]; - $kanbanData = json_encode($kanbanData); - return $this->sendSuccess(array('closeModal' => true, 'load' => true, 'callback' => "parent.updateKanban(\"story\", $kanbanData)")); + return $this->sendSuccess(array('load' => $browseLink)); } if($object->type == 'project') $this->project->setMenu($object->id); diff --git a/module/execution/js/linkstory.ui.js b/module/execution/js/linkstory.ui.js index 2af3c1cc07..d1d57ca2cc 100644 --- a/module/execution/js/linkstory.ui.js +++ b/module/execution/js/linkstory.ui.js @@ -1,5 +1,6 @@ -$(document).off('click','.batch-btn').on('click', '.batch-btn', function() +$(document).off('click','.batch-btn').on('click', '.batch-btn', function(e) { + const $modal = $(e.target).closest('.modal'); const dtable = zui.DTable.query($(this).target); const checkedList = dtable.$.getChecks(); if(!checkedList.length) return; @@ -8,9 +9,11 @@ $(document).off('click','.batch-btn').on('click', '.batch-btn', function() const form = new FormData(); checkedList.forEach((id) => form.append('stories[]', id)); + headers = {}; + if($modal.length > 0) headers = {'X-Zui-Modal': true}; if($(this).hasClass('ajax-btn')) { - $.ajaxSubmit({url, data: form}); + $.ajaxSubmit({url: url, data: form, headers: headers}); } else { diff --git a/module/execution/ui/importbug.html.php b/module/execution/ui/importbug.html.php index 956e0a6fe2..88ecf4ba76 100644 --- a/module/execution/ui/importbug.html.php +++ b/module/execution/ui/importbug.html.php @@ -16,12 +16,23 @@ featureBar ( set::current('all'), set::linkParams("executionID={$execution->id}"), - li - ( - searchToggle(set::module('importBug')) - ) + isInModal() ? null : li(searchToggle(set::module('importBug'))) ); +$footToolbar['items'][] = array( + 'text' => $lang->import, + 'className' => 'btn secondary import-bug-btn size-sm' +); +if(!isInModal()) +{ + $footToolbar['items'][] = array( + 'text' => $lang->goback, + 'className' => 'btn btn-info size-sm text-gray', + 'url' => createLink('execution', 'task', "executionID={$execution->id}"), + 'btnType' => 'info' + ); +} + $config->execution->importBug->dtable->fieldList['assignedTo']['controlItems'] = $users; formBase ( @@ -36,20 +47,7 @@ formBase set::checkable(true), set::showToolbarOnChecked(false), set::plugins(array('form')), - set::footToolbar(array( - 'items' => array( - array( - 'text' => $lang->import, - 'className' => 'btn secondary import-bug-btn size-sm' - ), - array( - 'text' => $lang->goback, - 'className' => 'btn btn-info size-sm text-gray', - 'url' => createLink('execution', 'task', "executionID={$execution->id}"), - 'btnType' => 'info' - ) - ) - )), + set::footToolbar($footToolbar), set::footPager( usePager(array('linkCreator' => helper::createLink('execution', 'importBug', "executionID={$execution->id}&browseType={$browseType}¶m=$param&recTotal={$pager->recTotal}&recPerPage={recPerPage}&page={page}"))) ) diff --git a/module/execution/ui/linkstory.html.php b/module/execution/ui/linkstory.html.php index f78550781f..59162c455c 100644 --- a/module/execution/ui/linkstory.html.php +++ b/module/execution/ui/linkstory.html.php @@ -15,28 +15,10 @@ namespace zin; featureBar(li ( setClass('nav-item'), - a - ( - setClass('active'), - $lang->execution->linkStory - ) + a(setClass('active'), $lang->execution->linkStory), + isInModal() ? null : li(searchToggle(set::module('story'))) )); -toolbar -( - btn(setClass('btn primary'), set::icon('back'), set::url($browseLink), $lang->goback) -); - -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); - -$footToolbar['items'][] = array -( - 'type' => 'btn-group', - 'items' => array( - array('text' => $lang->save, 'className' => "btn size-sm batch-btn ajax-btn link-story-btn", 'btnType' => 'secondary', 'data-url' => commonModel::isTutorialMode() ? '' : createLink('execution', 'linkStory', "objectID=$object->id")) - ) -); - $cols = $config->execution->linkStory->dtable->fieldList; $cols['module']['map'] = $modules; $cols['product']['map'] = $productPairs; @@ -51,6 +33,22 @@ else jsVar('branchGroups', $branchGroups); + +$footToolbar['items'][] = array( + 'text' => $lang->save, + 'className' => 'btn secondary batch-btn ajax-btn import-story-btn size-sm', + 'data-url' => createLink('execution', 'linkStory', "objectID=$object->id") +); +if(!isInModal()) +{ + $footToolbar['items'][] = array( + 'text' => $lang->goback, + 'className' => 'btn btn-info size-sm text-gray', + 'url' => $browseLink, + 'btnType' => 'info' + ); +} + dtable ( set::groupDivider(true), @@ -58,8 +56,9 @@ dtable set::cols($cols), set::data($allStories), set::checkable(true), - set::footToolbar($footToolbar), set::onRenderCell(jsRaw('window.onRenderLinkStoryCell')), + set::showToolbarOnChecked(false), + set::footToolbar($footToolbar), set::footPager(usePager(array( 'linkCreator' => helper::createLink($object->type, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&recPerPage={recPerPage}&page={page}&extra=$extra") ))) diff --git a/module/file/js/uploadimages.ui.js b/module/file/js/uploadimages.ui.js index 722b174cec..da6b614624 100644 --- a/module/file/js/uploadimages.ui.js +++ b/module/file/js/uploadimages.ui.js @@ -34,9 +34,31 @@ window.uploadImages = function() count++; if(count == length) { - var uploadimages = $uploadBox.zui('uploadimgs'); - var modalID = uploadimages.$element.closest('.modal').attr('id'); + let uploadimages = $uploadBox.zui('uploadimgs'); + let modalID = uploadimages.$element.closest('.modal').attr('id'); zui.Modal.hide('#' . modalID); + + const $form = $('body').find('form.form-batch[data-zui-batchform]'); + const $modal = $form.closest('.modal') + if($modal.length > 0) + { + $.ajax( + { + url: locateUrl, + headers:{'X-Zui-Modal': true}, + dataType: 'json', + success: function(data) + { + $modal.find('[data-zui-ajaxform]').zui('ajaxform').destroy(); + $modal.find('[data-zui-batchform]').zui('batchForm').destroy(); + setTimeout(function() + { + loadModal(data.load, $modal.attr('id')); + }, 500); + } + }); + return; + } loadPage(locateUrl); } }).catch(json => {$('.uploadBtn').removeAttr('disabled'); if(typeof(json.message) != 'undefined') zui.Modal.alert(json.message)}); diff --git a/module/kanban/model.php b/module/kanban/model.php index 9f65b9412b..66772f9623 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1929,18 +1929,26 @@ class kanbanModel extends model { $cardIdList = array_unique(array_filter(explode(',', $column->cards))); - $columnData = array(); - $columnData['id'] = $column->column; - $columnData['type'] = $column->columnType; - $columnData['name'] = $column->column; - $columnData['title'] = $column->columnName; - $columnData['color'] = $column->color; - $columnData['limit'] = $column->limit; - $columnData['region'] = $laneData['region']; - $columnData['laneName'] = $column->lane; - $columnData['group'] = $browseType; - $columnData['actionList'] = array('setColumn', 'setWIP'); - if($column->parent > 0) $columnData['parentName'] = $column->parent; + if(!isset($columnsData[$column->column])) + { + $columnData = array(); + $columnData['id'] = $column->column; + $columnData['type'] = $column->columnType; + $columnData['name'] = $column->column; + $columnData['title'] = $column->columnName; + $columnData['color'] = $column->color; + $columnData['limit'] = $column->limit; + $columnData['region'] = $laneData['region']; + $columnData['laneName'] = $column->lane; + $columnData['group'] = $browseType; + $columnData['cards'] = 0; + $columnData['actionList'] = array('setColumn', 'setWIP'); + if($column->parent > 0) $columnData['parentName'] = $column->parent; + } + else + { + $columnData = $columnsData[$column->column]; + } $cardCount = 0; $objects = zget($cardGroup, $column->columnType, array()); @@ -1974,7 +1982,7 @@ class kanbanModel extends model $cardsData[$laneData['id']][$column->column][] = $cardData; $cardCount++; } - $columnData['cards'] = $cardCount; + $columnData['cards'] += $cardCount; $columnsData[$column->column] = $columnData; } $lanesData[] = $laneData; From f4bfde58af8f2480969cf5c4d8cf7de69cf48d0e Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 15:49:33 +0800 Subject: [PATCH 069/235] * Fix type error. --- module/release/control.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/release/control.php b/module/release/control.php index 123ca746e3..1850b181b2 100644 --- a/module/release/control.php +++ b/module/release/control.php @@ -358,8 +358,8 @@ class release extends control $executionIdList = array(); foreach($builds as $build) { - if(!empty($build->execution)) $executionIdList[$build->execution] = $build->execution; - if(empty($build->execution) && !empty($build->project)) $executionIdList[$build->project] = $build->project; + if(!empty($build->execution)) $executionIdList[$build->execution] = (int)$build->execution; + if(empty($build->execution) && !empty($build->project)) $executionIdList[$build->project] = (int)$build->project; } /* Load pager. */ From 1788206c1ce124fbcfe15dff2dadd36e11310932 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Thu, 16 Nov 2023 16:12:05 +0800 Subject: [PATCH 070/235] * Fix zentao install date. --- db/update18.8.sql | 7 +++++++ db/zentao.sql | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/db/update18.8.sql b/db/update18.8.sql index 4877bbbf51..dceb5ab615 100644 --- a/db/update18.8.sql +++ b/db/update18.8.sql @@ -84,3 +84,10 @@ UPDATE `zt_chart` SET `type` = 'pie', `settings` = '[{\"type\":\"pie\",\"gro UPDATE `zt_chart` SET `type` = 'cluBarY', `settings` = '[{\"type\":\"cluBarY\",\"xaxis\":[{\"field\":\"joinDate\",\"name\":\"joinDate\",\"group\":\"\"}],\"yaxis\":[{\"field\":\"count\",\"name\":\"count\",\"valOrAgg\":\"sum\"}]}]', `fields` = '{\"count\":{\"name\":\"count\",\"object\":\"user\",\"field\":\"count\",\"type\":\"string\"},\"joinDate\":{\"name\":\"joinDate\",\"object\":\"user\",\"field\":\"joinDate\",\"type\":\"string\"}}', `langs` = '{\"count\":{\"zh-cn\":\"\\u4eba\\u6570\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"},\"joinDate\":{\"zh-cn\":\"\\u5de5\\u9f84\",\"zh-tw\":\"\",\"en\":\"\",\"de\":\"\",\"fr\":\"\"}}', `sql` = 'SELECT count(1) as count, \"0-1年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 1 YEAR)\nunion\nSELECT count(1) as count, \"1-3年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 3 YEAR) AND `join` <= DATE_SUB(NOW(), INTERVAL 1 YEAR)\nunion\nSELECT count(1) as count, \"3-5年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 5 YEAR) AND `join` <= DATE_SUB(NOW(), INTERVAL 3 YEAR)\nunion\nSELECT count(1) as count, \"5-10年\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` > DATE_SUB(NOW(), INTERVAL 10 YEAR) AND `join` <= DATE_SUB(NOW(), INTERVAL 5 YEAR)\nunion\nSELECT count(1) as count, \"10年以上\" as joinDate FROM zt_user WHERE deleted = \'0\' AND `join` < DATE_SUB(NOW(), INTERVAL 10 YEAR) AND LEFT(`join`, 4) != \'0000\'\nunion \nSELECT count(1) as count, \"未知\" as joinDate FROM zt_user WHERE deleted = \'0\' AND LEFT(`join`, 4) = \'0000\'', `stage` = 'published', `builtin` = 0 WHERE `id` = 1051; ALTER TABLE zt_metric DROP INDEX `code`; + +/* Add installed date to config. */ +INSERT INTO `zt_config` ( `vision`, `owner`, `module`, `section`, `key`, `value` ) VALUES ('', 'system', 'common', 'global', 'installedDate', (SELECT LEFT( date, 10 ) AS date FROM zt_action WHERE LEFT ( date, 10 ) != '2012-06-05' AND LEFT ( date, 10 ) != '2021-04-28' AND date > '2009-03-14' ORDER BY id LIMIT 1)); + +REPLACE INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1030, '宏观数据-禅道使用时长', 1, 'card', '58', '', '', '{\"value\": {\"type\": \"value\", \"field\": \"period\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\n\"type\": \"value\"\n}', '[]', 0, '', NULL, ' SELECT if(t2.`year` > 0, concat(t2.`year`, \'年\', t2.`day`, \'天\'), concat(t2.`day`, \'天\')) as period from (\r\nSELECT TIMESTAMPDIFF(YEAR,t1.firstDay,t1.today) AS `year`,DATEDIFF(DATE_SUB(t1.today,INTERVAL TIMESTAMPDIFF(YEAR,t1.firstDay,t1.today) YEAR), t1.firstDay) AS `day` \r\nFROM (SELECT `value` AS firstDay, now() AS today FROM zt_config WHERE `owner` = \'system\' AND `key` = \'installedDate\') AS t1\r\n) t2', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); +REPLACE INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (20015, '使用数据分析-上线时间', 1, 'card', '58', '0', ' ', '{\"value\": {\"type\": \"value\", \"field\": \"date\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"}, \"type\": \"value\"}', '[]', 0, ' ', NULL, 'select `value` as date from zt_config where `owner` = \'system\' and `key` = \'installedDate\'', 'published', 1, ' ', 'system', '2023-08-16 15:32:10', 'admin', '2023-08-16 15:32:17', 0); + diff --git a/db/zentao.sql b/db/zentao.sql index 351d83a1f0..83ac34aa26 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -16258,7 +16258,7 @@ INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `d INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1027, '宏观数据-文档个数', 1, 'card', '54', '', '', '{\"value\": {\"type\": \"agg\", \"field\": \"id\", \"agg\": \"count\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\r\n\"type\": \"value\"\r\n}', '[]', 0, '', NULL, 'SELECT id FROM zt_doc WHERE deleted=\'0\'', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1028, '宏观数据-现有人员个数', 1, 'card', '55', '', '', '{\"value\": {\"type\": \"agg\", \"field\": \"id\", \"agg\": \"count\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\r\n\"type\": \"value\"\r\n}', '[]', 0, '', NULL, 'SELECT id FROM zt_user WHERE deleted=\'0\'', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1029, '宏观数据-累计消耗工时', 1, 'card', '55', '', '', '{\"value\": {\"type\": \"agg\", \"field\": \"consumed\", \"agg\": \"sum\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\r\n\"type\": \"value\"\r\n}', '[]', 0, '', NULL, 'SELECT consumed FROM zt_effort WHERE deleted=\'0\'', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); -INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1030, '宏观数据-禅道使用时长', 1, 'card', '58', '', '', '{\"value\": {\"type\": \"value\", \"field\": \"period\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\n\"type\": \"value\"\n}', '[]', 0, '', NULL, 'SELECT if(t2.`year` > 0, concat(t2.`year`, \'年\', t2.`day`, \'天\'), concat(t2.`day`, \'天\')) as period from (\nSELECT TIMESTAMPDIFF(YEAR,t1.firstDay,t1.today) AS `year`,DATEDIFF(DATE_SUB(t1.today,INTERVAL TIMESTAMPDIFF(YEAR,t1.firstDay,t1.today) YEAR), t1.firstDay) AS `day` \nFROM (SELECT MIN(date) AS firstDay, now() AS today FROM zt_action WHERE date > \'1970-01-01\') AS t1\n) t2', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); +INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1030, '宏观数据-禅道使用时长', 1, 'card', '58', '', '', '{\"value\": {\"type\": \"value\", \"field\": \"period\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\n\"type\": \"value\"\n}', '[]', 0, '', NULL, ' SELECT if(t2.`year` > 0, concat(t2.`year`, \'年\', t2.`day`, \'天\'), concat(t2.`day`, \'天\')) as period from (\r\nSELECT TIMESTAMPDIFF(YEAR,t1.firstDay,t1.today) AS `year`,DATEDIFF(DATE_SUB(t1.today,INTERVAL TIMESTAMPDIFF(YEAR,t1.firstDay,t1.today) YEAR), t1.firstDay) AS `day` \r\nFROM (SELECT `value` AS firstDay, now() AS today FROM zt_config WHERE `owner` = \'system\' AND `key` = \'installedDate\') AS t1\r\n) t2', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1031, '宏观数据-需求完成率', 1, 'piecircle', '36', '', '', '{\"group\":[{\"field\":\"status\",\"name\":\"状态\"}],\"metric\":[{\"type\":\"agg\",\"field\":\"id\",\"agg\":\"count\",\"name\":\"需求数\",\"valOrAgg\":\"count\"}]}', '[]', 0, '', NULL, 'SELECT id, IF(closedReason=\'done\', \'done\', \'undone\') AS status FROM zt_story WHERE deleted=\'0\' AND (status != \'closed\' OR closedReason=\'done\')', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1032, '宏观数据-Bug修复率', 1, 'piecircle', '44', '', '', '{\"group\":[{\"field\":\"status\",\"name\":\"状态\"}],\"metric\":[{\"type\":\"agg\",\"field\":\"id\",\"agg\":\"count\",\"name\":\"Bug数\",\"valOrAgg\":\"count\"}]}', '[]', 0, '', NULL, 'SELECT id, IF(`status`=\'closed\' AND resolution=\'fixed\', \'done\', \'undone\') AS status FROM zt_bug WHERE deleted=\'0\' AND (status = \'active\' OR resolution in (\'fixed\', \'postponed\'))', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1033, '宏观数据-未完成的一级项目集个数', 1, 'card', '45', '', '', '{\"value\": {\"type\": \"agg\", \"field\": \"id\", \"agg\": \"count\"}, \"title\": {\"type\": \"text\", \"name\": \"\"},\r\n\"type\": \"value\"\r\n}', '[]', 0, '', NULL, 'SELECT id FROM zt_project WHERE type=\'program\' AND `status`!=\'closed\' AND deleted=\'0\' AND grade=\'1\'', 'published', 1, '', 'system', '2022-12-07 14:59:41', '', '2022-12-07 14:59:41', 0); @@ -16408,8 +16408,10 @@ INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `d INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (20012, '应用数据-产品需求概况表', 1, 'table', '36', '0', ' ', '{\"group\":[],\"column\":[{\"field\":\"name\",\"valOrAgg\":\"value\",\"name\":\"产品\"},{\"field\":\"createdStories\",\"valOrAgg\":\"value\",\"name\":\"新增研发需求数\"},{\"field\":\"deliveredStories\",\"valOrAgg\":\"value\",\"name\":\"交付需求数\"}],\"filter\":[]}', '[]', 0, ' ', NULL, 'SELECT * FROM\r\n(\r\nSELECT\r\n t1.id,\r\n t1.name,\r\n t3.year,\r\n t3.month,\r\n IFNULL(t1.count, 0) AS createdStories,\r\n IFNULL(t2.count, 0) AS deliveredStories \r\nFROM\r\n (\r\n select distinct year(date) as year, month(date) as month\r\n from zt_action\r\n )\r\n as t3 left join\r\n (\r\nSELECT\r\n t2.id,\r\n t2.NAME,\r\n YEAR ( t1.openedDate ) AS YEAR,\r\n MONTH ( t1.openedDate ) AS MONTH,\r\n COUNT( t1.id ) AS count \r\nFROM\r\n zt_story AS t1\r\n LEFT JOIN zt_product AS t2 ON t1.product = t2.id \r\nWHERE\r\n t2.deleted = \'0\'\r\n AND t1.deleted = \'0\'\r\n AND t1.type = \'story\'\r\nGROUP BY\r\n t2.id,\r\n YEAR,\r\nMONTH \r\n ) AS t1 on t3.year = t1.year and t3.month = t1.month\r\n LEFT JOIN (\r\nSELECT\r\n t1.id,\r\n t1.NAME,\r\n t1.YEAR,\r\n t1.MONTH,\r\n COUNT( distinct t1.story ) AS count \r\nFROM\r\n (\r\nSELECT\r\n t2.id,\r\n t2.NAME, \r\n YEAR ( t3.date ) AS YEAR,\r\n MONTH ( t3.date ) AS MONTH,\r\n t1.id AS story \r\nFROM\r\n zt_story AS t1\r\n LEFT JOIN zt_product AS t2 ON t1.product = t2.id\r\n LEFT JOIN ( SELECT objectID, MAX( date ) AS date FROM zt_action WHERE objectType = \'story\' AND action = \'linked2release\' GROUP BY objectID ) AS t3 ON t1.id = t3.objectID \r\nWHERE\r\n t1.deleted = \'0\' \r\n AND t2.deleted = \'0\' \r\n AND EXISTS ( SELECT 1 FROM zt_action WHERE objectID = t1.id AND objectType = \'story\' AND action = \'linked2release\' ) \r\nUNION\r\nSELECT\r\n t2.id,\r\n t2.NAME,\r\n YEAR ( t1.closedDate ) AS YEAR,\r\n MONTH ( t1.closedDate ) AS MONTH,\r\n t1.id AS story \r\nFROM\r\n zt_story AS t1\r\n LEFT JOIN zt_product AS t2 ON t1.product = t2.id \r\nWHERE\r\n t1.deleted = \'0\' \r\n AND t2.deleted = \'0\' \r\n AND t1.status = \'closed\' \r\n AND t1.closedReason = \'done\' \r\n ) AS t1 \r\nGROUP BY\r\n t1.id,\r\n t1.name,\r\n t1.YEAR,\r\n t1.MONTH order by id asc \r\n ) AS t2 ON t1.id = t2.id \r\n AND t3.YEAR = t2.YEAR \r\n AND t3.MONTH = t2.MONTH\r\n) AS t\r\nWHERE t.name IS NOT NULL', 'published', 1, ' ', 'system', '2023-08-16 13:37:24', 'admin', '2023-08-16 13:37:24', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (20013, '应用数据-项目需求概况表', 1, 'table', '43', '0', ' ', '{\"group\":[],\"column\":[{\"field\":\"name\",\"valOrAgg\":\"value\",\"name\":\"项目\"},{\"field\":\"createdStories\",\"valOrAgg\":\"value\",\"name\":\"新增研发需求数\"},{\"field\":\"deliveredStories\",\"valOrAgg\":\"value\",\"name\":\"交付需求数\"}],\"filter\":[]}', '[]', 0, ' ', NULL, 'SELECT * FROM (\r\nSELECT\r\n t1.id,\r\n t1.name,\r\n t3.year,\r\n t3.month,\r\n IFNULL(t1.count, 0) AS createdStories,\r\n IFNULL(t2.count, 0) AS deliveredStories \r\nFROM\r\n (\r\n select distinct year(date) as year, month(date) as month\r\n from zt_action\r\n )\r\n as t3 left join\r\n (\r\nSELECT\r\n t3.id,\r\n t3.NAME,\r\n YEAR ( t1.openedDate ) AS YEAR,\r\n MONTH ( t1.openedDate ) AS MONTH,\r\n COUNT( t1.id ) AS count \r\nFROM\r\n zt_story AS t1\r\n LEFT JOIN zt_projectstory AS t2 ON t1.id = t2.story\r\n LEFT JOIN zt_project AS t3 ON t2.project = t3.id \r\nWHERE\r\n t3.type = \'project\' \r\n AND t1.deleted = \'0\' \r\n AND t3.deleted = \'0\' \r\nGROUP BY\r\n t3.id,\r\n YEAR,\r\nMONTH \r\n ) AS t1 on t1.year = t3.year and t1.month = t3.month\r\n LEFT JOIN (\r\nSELECT\r\n t1.id,\r\n t1.NAME,\r\n t1.YEAR,\r\n t1.MONTH,\r\n COUNT( t1.story ) AS count \r\nFROM\r\n (\r\nSELECT\r\n t3.id,\r\n t3.NAME,\r\n YEAR ( t4.date ) AS YEAR,\r\n MONTH ( t4.date ) AS MONTH,\r\n t1.id AS story \r\nFROM\r\n zt_story AS t1\r\n LEFT JOIN zt_projectstory AS t2 ON t1.id = t2.story\r\n LEFT JOIN zt_project AS t3 ON t2.project = t3.id\r\n LEFT JOIN ( SELECT objectID, MAX( date ) AS date FROM zt_action WHERE objectType = \'story\' AND action = \'linked2release\' GROUP BY objectID ) AS t4 ON t1.id = t4.objectID \r\nWHERE\r\n t3.type = \'project\' \r\n AND t1.deleted = \'0\' \r\n AND t3.deleted = \'0\' \r\n AND EXISTS ( SELECT 1 FROM zt_action WHERE objectID = t1.id AND objectType = \'story\' AND action = \'linked2release\' ) UNION\r\nSELECT\r\n t3.id,\r\n t3.NAME,\r\n YEAR ( t1.closedDate ) AS YEAR,\r\n MONTH ( t1.closedDate ) AS MONTH,\r\n t1.id AS story \r\nFROM\r\n zt_story AS t1\r\n LEFT JOIN zt_projectstory AS t2 ON t1.id = t2.story\r\n LEFT JOIN zt_project AS t3 ON t2.project = t3.id \r\nWHERE\r\n t3.type = \'project\' \r\n AND t1.STATUS = \'closed\' \r\n AND t1.closedReason = \'done\' \r\n AND t1.deleted = \'0\' \r\n AND t3.deleted = \'0\' \r\n ) AS t1 \r\nGROUP BY\r\n t1.id,\r\n t1.name,\r\n t1.YEAR,\r\n t1.MONTH \r\n ) AS t2 ON t1.id = t2.id \r\n AND t3.YEAR = t2.YEAR \r\n AND t3.MONTH = t2.MONTH\r\n) AS t WHERE t.id IS NOT NULL', 'published', 1, ' ', 'system', '2023-08-16 13:37:24', 'admin', '2023-08-16 13:37:24', 0); INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (20014, '使用数据分析-当前版本', 1, 'card', '58', '0', ' ', '{\"value\": {\"type\": \"value\", \"field\": \"version\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"}, \"type\": \"value\"}', ' ', 0, ' ', NULL, 'SELECT REPLACE(REPLACE(REPLACE(value, \'max\', \'旗舰版\'), \'biz\', \'企业版\'), \'pro\', \'专业版\') as version FROM zt_config WHERE owner = \'system\' AND module = \'common\' AND section = \'global\' AND `key` = \'version\'', 'published', 1, ' ', 'system', '2023-08-16 15:28:35', 'admin', '2023-08-16 15:28:41', 0); -INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (20015, '使用数据分析-上线时间', 1, 'card', '58', '0', ' ', '{\"value\": {\"type\": \"value\", \"field\": \"date\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"}, \"type\": \"value\"}', '[]', 0, ' ', NULL, 'select concat(year(date), \'-\', month(date), \'-\', day(date)) as date from zt_action order by id asc limit 1', 'published', 1, ' ', 'system', '2023-08-16 15:32:10', 'admin', '2023-08-16 15:32:17', 0); +INSERT INTO `zt_chart`(`id`, `name`, `dimension`, `type`, `group`, `dataset`, `desc`, `settings`, `filters`, `step`, `fields`, `langs`, `sql`, `stage`, `builtin`, `objects`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (20015, '使用数据分析-上线时间', 1, 'card', '58', '0', ' ', '{\"value\": {\"type\": \"value\", \"field\": \"date\", \"agg\": \"value\"}, \"title\": {\"type\": \"text\", \"name\": \"\"}, \"type\": \"value\"}', '[]', 0, ' ', NULL, 'select `value` as date from zt_config where `owner` = \'system\' and `key` = \'installedDate\'', 'published', 1, ' ', 'system', '2023-08-16 15:32:10', 'admin', '2023-08-16 15:32:17', 0); INSERT INTO `zt_screen`(`id`, `dimension`, `name`, `desc`, `cover`, `scheme`, `status`, `builtin`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `deleted`) VALUES (1001, 1, '禅道月度应用健康度体检大屏', '公司级禅道应用健康度体检大屏,促进项目管理持续改进。', '', '[{\"id\":\"5scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":120,\"x\":0,\"y\":0,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":1300,\"h\":120,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static\\/images\\/screen_header.png\",\"borderRadius\":10}},{\"id\":\"2nws38440fq000\",\"isGroup\":false,\"attr\":{\"x\":400,\"y\":36,\"w\":500,\"h\":66,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"title\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u7985\\u9053\\u6708\\u5ea6\\u5e94\\u7528\\u5065\\u5eb7\\u5ea6\\u4f53\\u68c0\\u62a5\\u544a\",\"fontSize\":20,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"5scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":300,\"h\":120,\"x\":0,\"y\":95,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"type\":\"year\",\"filterCharts\":[{\"chart\":20001,\"field\":\"t1.`year`\"},{\"chart\":20002,\"field\":\"t1.`year`\"},{\"chart\":20003,\"field\":\"t1.`year`\"},{\"chart\":20004,\"field\":\"t1.`year`\"},{\"chart\":20005,\"field\":\"t1.`year`\"},{\"chart\":20006,\"field\":\"t1.`year`\"},{\"chart\":20007,\"field\":\"t1.`year`\"},{\"chart\":20008,\"field\":\"t1.`year`\"},{\"chart\":20009,\"field\":\"t1.`year`\"},{\"chart\":20010,\"field\":\"t1.`year`\"},{\"chart\":20011,\"field\":\"t1.`year`\"},{\"chart\":20012,\"field\":\"t1.`year`\"},{\"chart\":20013,\"field\":\"t1.`year`\"}],\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":100,\"h\":120,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Select\",\"chartConfig\":{\"key\":\"Select\",\"chartKey\":\"VSelect\",\"conKey\":\"VCSelect\",\"title\":\"\\u9009\\u62e9\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/select-c616737a.png\"},\"option\":{\"dataset\":[{\"label\":\"\\u8bf7\\u9009\\u62e9\",\"value\":\"\"},{\"label\":\"\\u6cb3\\u5317\",\"value\":\"18700\"},{\"label\":\"\\u5f90\\u5dde\",\"value\":\"17800\"}],\"value\":\"\",\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"background\":\"none\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"backgroundColor\":\"transparent\",\"fontSize\":20,\"onChange\":\"console.log(value)\"}},{\"id\":\"2xjom2cw2b2000\",\"type\":\"month\",\"filterCharts\":[{\"chart\":20001,\"field\":\"t1.`month`\"},{\"chart\":20002,\"field\":\"t1.`month`\"},{\"chart\":20003,\"field\":\"t1.`month`\"},{\"chart\":20004,\"field\":\"t1.`month`\"},{\"chart\":20005,\"field\":\"t1.`month`\"},{\"chart\":20006,\"field\":\"t1.`month`\"},{\"chart\":20007,\"field\":\"t1.`month`\"},{\"chart\":20008,\"field\":\"t1.`month`\"},{\"chart\":20009,\"field\":\"t1.`month`\"},{\"chart\":20010,\"field\":\"t1.`month`\"},{\"chart\":20011,\"field\":\"t1.`month`\"},{\"chart\":20012,\"field\":\"t1.`month`\"},{\"chart\":20013,\"field\":\"t1.`month`\"}],\"isGroup\":false,\"attr\":{\"x\":100,\"y\":0,\"w\":100,\"h\":120,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Select\",\"chartConfig\":{\"key\":\"Select\",\"chartKey\":\"VSelect\",\"conKey\":\"VCSelect\",\"title\":\"\\u9009\\u62e9\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/select-c616737a.png\"},\"option\":{\"dataset\":[{\"label\":\"\\u8bf7\\u9009\\u62e9\",\"value\":\"\"},{\"label\":\"\\u6cb3\\u5317\",\"value\":\"18700\"},{\"label\":\"\\u5f90\\u5dde\",\"value\":\"17800\"}],\"value\":\"\",\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"background\":\"none\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"backgroundColor\":\"transparent\",\"fontSize\":20,\"onChange\":\"console.log(value)\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":150,\"w\":1300,\"h\":220,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":80,\"x\":0,\"y\":150,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":230,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u4f7f\\u7528\\u6570\\u636e\\u5206\\u6790\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":25,\"y\":220,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":390,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20014,\"isGroup\":false,\"attr\":{\"x\":110,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":110,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u5f53\\u524d\\u7248\\u672c\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":448,\"y\":220,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":390,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20015,\"isGroup\":false,\"attr\":{\"x\":110,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":110,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u4e0a\\u7ebf\\u65f6\\u95f4\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":870,\"y\":220,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":390,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":1028,\"isGroup\":false,\"attr\":{\"x\":110,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":110,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u540e\\u53f0\\u8d26\\u53f7\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":375,\"w\":1300,\"h\":525,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":120,\"x\":0,\"y\":375,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":277,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u6d3b\\u8dc3\\u8d26\\u53f7\\u6570\\u9879\\u76ee\\u95f4\\u5bf9\\u6bd4\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"1zhfrmecpnxc00\",\"sourceID\":20002,\"isGroup\":false,\"attr\":{\"x\":25,\"y\":57,\"w\":1250,\"h\":446,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TableScrollBoard\",\"chartConfig\":{\"key\":\"TableScrollBoard\",\"chartKey\":\"VTableScrollBoard\",\"conKey\":\"VCTableScrollBoard\",\"title\":\"\\u8f6e\\u64ad\\u5217\\u8868\",\"category\":\"Tables\",\"categoryName\":\"\\u8868\\u683c\",\"package\":\"Tables\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/table_scrollboard-fb642e78.png\"},\"option\":{\"header\":[\"\\u52171\",\"\\u52172\",\"\\u52173\"],\"dataset\":[[\"\\u884c1\\u52171\",\"\\u884c1\\u52172\",\"\\u884c1\\u52173\"],[\"\\u884c2\\u52171\",\"\\u884c2\\u52172\",\"\\u884c2\\u52173\"],[\"\\u884c3\\u52171\",\"\\u884c3\\u52172\",\"\\u884c3\\u52173\"],[\"\\u884c4\\u52171\",\"\\u884c4\\u52172\",\"\\u884c4\\u52173\"],[\"\\u884c5\\u52171\",\"\\u884c5\\u52172\",\"\\u884c5\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"]],\"index\":false,\"columnWidth\":[],\"align\":[\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\"],\"rowNum\":8,\"waitTime\":3,\"headerHeight\":45,\"carousel\":\"single\",\"headerBGC\":\"#165896FF\",\"oddRowBGC\":\"#042b4dFF\",\"evenRowBGC\":\"#0a1c37FF\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"3hqq7oh18ra000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":500,\"x\":0,\"y\":905,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u516c\\u53f8\\u8d26\\u53f7\\u65e5\\u6d3b\\u8dc3\\u5ea6\\u8d8b\\u52bf\\u7edf\\u8ba1\",\"image\":\"\"},\"groupList\":[{\"id\":\"1dlpgwe8wwe800\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":1300,\"h\":500,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"\\u516c\\u53f8\\u8d26\\u53f7\\u65e5\\u6d3b\\u8dc3\\u5ea6\\u8d8b\\u52bf\\u7edf\\u8ba1\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#0a1c3700\",\"#042b4d00\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"obhxxjnin3400\",\"sourceID\":20003,\"isGroup\":false,\"attr\":{\"x\":0,\"y\":60,\"w\":1250,\"h\":416,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"LineCommon\",\"chartConfig\":{\"key\":\"LineCommon\",\"chartKey\":\"VLineCommon\",\"conKey\":\"VCLineCommon\",\"title\":\"\\u6298\\u7ebf\\u56fe\",\"category\":\"Lines\",\"categoryName\":\"\\u6298\\u7ebf\\u56fe\",\"package\":\"Charts\",\"chartFrame\":\"echarts\",\"image\":\"static\\/png\\/line.png\"},\"option\":{\"legend\":{\"show\":true,\"bottom\":\"5%\",\"textStyle\":{\"color\":\"#B9B8CE\"}},\"xAxis\":{\"show\":true,\"name\":\"(\\u65e5\\u671f)\",\"nameGap\":15,\"nameTextStyle\":{\"color\":\"#B9B8CE\",\"fontSize\":12},\"inverse\":false,\"axisLabel\":{\"show\":true,\"fontSize\":12,\"color\":\"#B9B8CE\",\"rotate\":0},\"position\":\"bottom\",\"axisLine\":{\"show\":true,\"lineStyle\":{\"color\":\"#B9B8CE\",\"width\":1},\"onZero\":true},\"axisTick\":{\"show\":true,\"length\":5},\"splitLine\":{\"show\":false,\"lineStyle\":{\"color\":\"#484753\",\"width\":1,\"type\":\"solid\"}},\"type\":\"category\"},\"yAxis\":{\"show\":true,\"name\":\"(\\u4e2a\\u6570)\",\"nameGap\":15,\"nameTextStyle\":{\"color\":\"#B9B8CE\",\"fontSize\":12},\"inverse\":false,\"axisLabel\":{\"show\":true,\"fontSize\":12,\"color\":\"#B9B8CE\",\"rotate\":0},\"position\":\"left\",\"axisLine\":{\"show\":true,\"lineStyle\":{\"color\":\"#B9B8CE\",\"width\":1},\"onZero\":true},\"axisTick\":{\"show\":true,\"length\":5},\"splitLine\":{\"show\":true,\"lineStyle\":{\"color\":\"#484753\",\"width\":1,\"type\":\"solid\"}},\"type\":\"value\"},\"grid\":{\"show\":false,\"left\":\"10%\",\"top\":\"30\",\"right\":\"10%\",\"bottom\":\"60\"},\"tooltip\":{\"show\":true,\"trigger\":\"axis\",\"axisPointer\":{\"type\":\"line\"}},\"dataset\":{\"dimensions\":[\"product\",\"data1\",\"data2\"],\"source\":[{\"product\":\"Mon\",\"data1\":120,\"data2\":130},{\"product\":\"Tue\",\"data1\":200,\"data2\":130},{\"product\":\"Wed\",\"data1\":150,\"data2\":312},{\"product\":\"Thu\",\"data1\":80,\"data2\":268},{\"product\":\"Fri\",\"data1\":70,\"data2\":155},{\"product\":\"Sat\",\"data1\":110,\"data2\":117},{\"product\":\"Sun\",\"data1\":130,\"data2\":160}]},\"series\":[{\"type\":\"line\",\"label\":{\"show\":true,\"position\":\"top\",\"color\":\"#fff\",\"fontSize\":12},\"symbolSize\":5,\"itemStyle\":{\"color\":null,\"borderRadius\":0},\"lineStyle\":{\"type\":\"solid\",\"width\":3,\"color\":null}},{\"type\":\"line\",\"label\":{\"show\":true,\"position\":\"top\",\"color\":\"#fff\",\"fontSize\":12},\"symbolSize\":5,\"itemStyle\":{\"color\":null,\"borderRadius\":0},\"lineStyle\":{\"type\":\"solid\",\"width\":3,\"color\":null}}],\"backgroundColor\":\"rgba(0,0,0,0)\"}},{\"id\":\"2u3zlsz5kk4000\",\"isGroup\":false,\"attr\":{\"x\":17,\"y\":0,\"w\":250,\"h\":72,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u516c\\u53f8\\u8d26\\u53f7\\u65e5\\u6d3b\\u8dc3\\u5ea6\\u8d8b\\u52bf\\u7edf\\u8ba1\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u516c\\u53f8\\u8d26\\u53f7\\u65e5\\u6d3b\\u8dc3\\u5ea6\\u8d8b\\u52bf\\u7edf\\u8ba1\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":1405,\"w\":1300,\"h\":400,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":80,\"x\":0,\"y\":1400,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":230,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u4ea7\\u54c1\\u6570\\u636e\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":25,\"y\":1470,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":390,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":1020,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":100,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u5f53\\u524d\\u4ea7\\u54c1\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":448,\"y\":1470,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":390,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20004,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":100,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u6d3b\\u8dc3\\u4ea7\\u54c1\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":870,\"y\":1470,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":390,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20005,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":100,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u672c\\u6708\\u65b0\\u589e\\u4ea7\\u54c1\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":159,\"x\":25,\"y\":1630,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":1240,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20006,\"isGroup\":false,\"attr\":{\"x\":110,\"y\":20,\"w\":1000,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":525,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u672c\\u6708\\u65b0\\u589e\\u4ea7\\u54c1\\u540d\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":2855,\"w\":1300,\"h\":400,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":80,\"x\":0,\"y\":2855,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":230,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u9879\\u76ee\\u6570\\u636e\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":25,\"y\":2925,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":370,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":1019,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":100,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u5f53\\u524d\\u9879\\u76ee\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":448,\"y\":2925,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":370,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20007,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":100,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u6d3b\\u8dc3\\u9879\\u76ee\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":180,\"h\":159,\"x\":870,\"y\":2925,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":370,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20008,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":169,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":100,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u672c\\u6708\\u65b0\\u589e\\u9879\\u76ee\\u6570\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"z3gs9qz8hq800\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":159,\"x\":25,\"y\":3080,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6587\\u6863\\u4e2a\\u6570\",\"image\":\"\"},\"groupList\":[{\"id\":\"2xjom2cw2b2000\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":0,\"w\":1215,\"h\":127,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Image\",\"chartConfig\":{\"key\":\"Image\",\"chartKey\":\"VImage\",\"conKey\":\"VCImage\",\"title\":\"header\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static/png/photo-637bc05d.png\"},\"option\":{\"dataset\":\"static/images/card.png\",\"borderRadius\":0}},{\"id\":\"3ef3nnqh7gu00\",\"sourceID\":20009,\"isGroup\":false,\"attr\":{\"x\":100,\"y\":20,\"w\":1000,\"h\":48,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"100\",\"fontSize\":15,\"fontColor\":\"#ffffff\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"normal\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"52mwo993eaw000\",\"isGroup\":false,\"attr\":{\"x\":515,\"y\":50,\"w\":169,\"h\":78,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"\\u4e00\\u7ea7\\u9879\\u76ee\\u96c6\\u4e2a\\u6570\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static/png/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http://\",\"dataset\":\"\\u672c\\u6708\\u65b0\\u589e\\u9879\\u76ee\\u540d\",\"fontSize\":15,\"fontColor\":\"#9abdcd\",\"paddingX\":0,\"paddingY\":0,\"textAlign\":\"center\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":1,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":3780,\"w\":1300,\"h\":525,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":120,\"x\":0,\"y\":3780,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":277,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u9879\\u76ee\\u4efb\\u52a1\\u6982\\u51b5\\u8868\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"1zhfrmecpnxc00\",\"sourceID\":20010,\"isGroup\":false,\"attr\":{\"x\":25,\"y\":57,\"w\":1250,\"h\":446,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TableScrollBoard\",\"chartConfig\":{\"key\":\"TableScrollBoard\",\"chartKey\":\"VTableScrollBoard\",\"conKey\":\"VCTableScrollBoard\",\"title\":\"\\u8f6e\\u64ad\\u5217\\u8868\",\"category\":\"Tables\",\"categoryName\":\"\\u8868\\u683c\",\"package\":\"Tables\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/table_scrollboard-fb642e78.png\"},\"option\":{\"header\":[\"\\u52171\",\"\\u52172\",\"\\u52173\"],\"dataset\":[[\"\\u884c1\\u52171\",\"\\u884c1\\u52172\",\"\\u884c1\\u52173\"],[\"\\u884c2\\u52171\",\"\\u884c2\\u52172\",\"\\u884c2\\u52173\"],[\"\\u884c3\\u52171\",\"\\u884c3\\u52172\",\"\\u884c3\\u52173\"],[\"\\u884c4\\u52171\",\"\\u884c4\\u52172\",\"\\u884c4\\u52173\"],[\"\\u884c5\\u52171\",\"\\u884c5\\u52172\",\"\\u884c5\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"]],\"index\":false,\"columnWidth\":[],\"align\":[\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\"],\"rowNum\":8,\"waitTime\":3,\"headerHeight\":45,\"carousel\":\"single\",\"headerBGC\":\"#165896FF\",\"oddRowBGC\":\"#042b4dFF\",\"evenRowBGC\":\"#0a1c37FF\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":3255,\"w\":1300,\"h\":525,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":120,\"x\":0,\"y\":3255,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":277,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u9879\\u76ee\\u9700\\u6c42\\u6982\\u51b5\\u8868\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"1zhfrmecpnxc00\",\"sourceID\":20013,\"isGroup\":false,\"attr\":{\"x\":25,\"y\":57,\"w\":1250,\"h\":446,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TableScrollBoard\",\"chartConfig\":{\"key\":\"TableScrollBoard\",\"chartKey\":\"VTableScrollBoard\",\"conKey\":\"VCTableScrollBoard\",\"title\":\"\\u8f6e\\u64ad\\u5217\\u8868\",\"category\":\"Tables\",\"categoryName\":\"\\u8868\\u683c\",\"package\":\"Tables\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/table_scrollboard-fb642e78.png\"},\"option\":{\"header\":[\"\\u52171\",\"\\u52172\",\"\\u52173\"],\"dataset\":[[\"\\u884c1\\u52171\",\"\\u884c1\\u52172\",\"\\u884c1\\u52173\"],[\"\\u884c2\\u52171\",\"\\u884c2\\u52172\",\"\\u884c2\\u52173\"],[\"\\u884c3\\u52171\",\"\\u884c3\\u52172\",\"\\u884c3\\u52173\"],[\"\\u884c4\\u52171\",\"\\u884c4\\u52172\",\"\\u884c4\\u52173\"],[\"\\u884c5\\u52171\",\"\\u884c5\\u52172\",\"\\u884c5\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"]],\"index\":false,\"columnWidth\":[],\"align\":[\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\"],\"rowNum\":8,\"waitTime\":3,\"headerHeight\":45,\"carousel\":\"single\",\"headerBGC\":\"#165896FF\",\"oddRowBGC\":\"#042b4dFF\",\"evenRowBGC\":\"#0a1c37FF\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":2330,\"w\":1300,\"h\":525,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":120,\"x\":0,\"y\":2330,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":277,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u4ea7\\u54c1\\u6d4b\\u8bd5\\u8868\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"1zhfrmecpnxc00\",\"sourceID\":20011,\"isGroup\":false,\"attr\":{\"x\":25,\"y\":57,\"w\":1250,\"h\":446,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TableScrollBoard\",\"chartConfig\":{\"key\":\"TableScrollBoard\",\"chartKey\":\"VTableScrollBoard\",\"conKey\":\"VCTableScrollBoard\",\"title\":\"\\u8f6e\\u64ad\\u5217\\u8868\",\"category\":\"Tables\",\"categoryName\":\"\\u8868\\u683c\",\"package\":\"Tables\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/table_scrollboard-fb642e78.png\"},\"option\":{\"header\":[\"\\u52171\",\"\\u52172\",\"\\u52173\"],\"dataset\":[[\"\\u884c1\\u52171\",\"\\u884c1\\u52172\",\"\\u884c1\\u52173\"],[\"\\u884c2\\u52171\",\"\\u884c2\\u52172\",\"\\u884c2\\u52173\"],[\"\\u884c3\\u52171\",\"\\u884c3\\u52172\",\"\\u884c3\\u52173\"],[\"\\u884c4\\u52171\",\"\\u884c4\\u52172\",\"\\u884c4\\u52173\"],[\"\\u884c5\\u52171\",\"\\u884c5\\u52172\",\"\\u884c5\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"]],\"index\":false,\"columnWidth\":[],\"align\":[\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\"],\"rowNum\":8,\"waitTime\":3,\"headerHeight\":45,\"carousel\":\"single\",\"headerBGC\":\"#165896FF\",\"oddRowBGC\":\"#042b4dFF\",\"evenRowBGC\":\"#0a1c37FF\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"1cfwp95aiif400\",\"isGroup\":false,\"attr\":{\"x\":0,\"y\":1805,\"w\":1300,\"h\":525,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"Border03\",\"chartConfig\":{\"key\":\"Border03\",\"chartKey\":\"VBorder03\",\"conKey\":\"VCBorder03\",\"title\":\"summary\",\"category\":\"Borders\",\"categoryName\":\"\\u8fb9\\u6846\",\"package\":\"Decorates\",\"image\":\"\"},\"option\":{\"colors\":[\"#00102800\",\"#00102800\"],\"backgroundColor\":\"#0a1c38\"}},{\"id\":\"6scfjzqsbzo000\",\"isGroup\":true,\"attr\":{\"w\":1300,\"h\":120,\"x\":0,\"y\":1805,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"chartConfig\":{\"key\":\"group\",\"chartKey\":\"group\",\"conKey\":\"group\",\"category\":\"group\",\"categoryName\":\"group\",\"package\":\"group\",\"chartFrame\":\"common\",\"title\":\"\\u6807\\u9898\",\"image\":\"\"},\"groupList\":[{\"id\":\"57r67ykkwxk000\",\"isGroup\":false,\"attr\":{\"x\":15,\"y\":0,\"w\":277,\"h\":68,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TextCommon\",\"chartConfig\":{\"key\":\"TextCommon\",\"chartKey\":\"VTextCommon\",\"conKey\":\"VCTextCommon\",\"title\":\"summary_top\",\"category\":\"Texts\",\"categoryName\":\"\\u6587\\u672c\",\"package\":\"Informations\",\"image\":\"static\\/png\\/text_static-b2721032.png\"},\"option\":{\"link\":\"\",\"linkHead\":\"http:\\/\\/\",\"dataset\":\"\\u4ea7\\u54c1\\u9700\\u6c42\\u6982\\u51b5\\u8868\",\"fontSize\":14,\"fontColor\":\"#b2d5e5\",\"paddingX\":10,\"paddingY\":10,\"textAlign\":\"left\",\"fontWeight\":\"bold\",\"borderWidth\":0,\"borderColor\":\"#ffffff\",\"borderRadius\":5,\"letterSpacing\":5,\"writingMode\":\"horizontal-tb\",\"backgroundColor\":\"#00000000\"}},{\"id\":\"1zhfrmecpnxc00\",\"sourceID\":20012,\"isGroup\":false,\"attr\":{\"x\":25,\"y\":57,\"w\":1250,\"h\":446,\"offsetX\":0,\"offsetY\":0,\"zIndex\":-1},\"key\":\"TableScrollBoard\",\"chartConfig\":{\"key\":\"TableScrollBoard\",\"chartKey\":\"VTableScrollBoard\",\"conKey\":\"VCTableScrollBoard\",\"title\":\"\\u8f6e\\u64ad\\u5217\\u8868\",\"category\":\"Tables\",\"categoryName\":\"\\u8868\\u683c\",\"package\":\"Tables\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/table_scrollboard-fb642e78.png\"},\"option\":{\"header\":[\"\\u52171\",\"\\u52172\",\"\\u52173\"],\"dataset\":[[\"\\u884c1\\u52171\",\"\\u884c1\\u52172\",\"\\u884c1\\u52173\"],[\"\\u884c2\\u52171\",\"\\u884c2\\u52172\",\"\\u884c2\\u52173\"],[\"\\u884c3\\u52171\",\"\\u884c3\\u52172\",\"\\u884c3\\u52173\"],[\"\\u884c4\\u52171\",\"\\u884c4\\u52172\",\"\\u884c4\\u52173\"],[\"\\u884c5\\u52171\",\"\\u884c5\\u52172\",\"\\u884c5\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"],[\"\\u884c6\\u52171\",\"\\u884c6\\u52172\",\"\\u884c6\\u52173\"]],\"index\":false,\"columnWidth\":[],\"align\":[\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\",\"center\"],\"rowNum\":8,\"waitTime\":3,\"headerHeight\":45,\"carousel\":\"single\",\"headerBGC\":\"#165896FF\",\"oddRowBGC\":\"#042b4dFF\",\"evenRowBGC\":\"#0a1c37FF\"}}],\"key\":\"group\",\"option\":{}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":173,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u4e0a\\u7ebf\\u65f6\\u95f4\\uff1a\\u7ba1\\u7406\\u5458\\u9996\\u6b21\\u767b\\u5f55\\u7985\\u9053\\u7684\\u65f6\\u95f4\\u3002\\u000A\\u540e\\u53f0\\u8d26\\u53f7\\u6570\\uff1a\\u7cfb\\u7edf\\u6240\\u6709\\u8d26\\u53f7\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u8d26\\u53f7\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":395,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u67d0\\u6708\\u56e2\\u961f\\u8d26\\u53f7\\u6570\\uff1a\\u56e2\\u961f\\u6240\\u6709\\u8d26\\u53f7\\u6570\\u6c42\\u548c\\uff0c\\u52a0\\u5165\\u65f6\\u95f4\\u003c\\u003d\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u8d26\\u53f7\\u6570\\u3002\\u000A\\u67d0\\u6708\\u6d3b\\u8dc3\\u8d26\\u53f7\\u6570\\uff1a\\u56e2\\u961f\\u8d26\\u53f7\\u4e2d\\uff0c\\u5728\\u67d0\\u6708\\u6709\\u8fc7\\u767b\\u5f55\\u884c\\u4e3a\\u7684\\u8d26\\u53f7\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u8d26\\u53f7\\u3002\\u000A\\u67d0\\u6708\\u6d3b\\u8dc3\\u8d26\\u53f7\\u6bd4\\uff1a\\u67d0\\u6708\\u6d3b\\u8dc3\\u8d26\\u53f7\\u6bd4\\u003d\\u67d0\\u6708\\u6d3b\\u8dc3\\u8d26\\u53f7\\u6570\\u002f\\u67d0\\u6708\\u56e2\\u961f\\u8d26\\u53f7\\u6570\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":925,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u5728\\u67d0\\u6708\\uff0c\\u516c\\u53f8\\u6bcf\\u65e5\\u6709\\u767b\\u5f55\\u884c\\u4e3a\\u7684\\u8d26\\u53f7\\u6570\\u6c42\\u548c\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":1419,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u5f53\\u524d\\u4ea7\\u54c1\\u6570\\uff1a\\u7cfb\\u7edf\\u4e2d\\u6240\\u6709\\u4ea7\\u54c1\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u67d0\\u6708\\u6d3b\\u8dc3\\u4ea7\\u54c1\\u6570\\uff1a\\u7cfb\\u7edf\\u4e2d\\u67d0\\u6708\\u6709\\u8fc7\\u52a8\\u6001\\u7684\\u4ea7\\u54c1\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u67d0\\u6708\\u65b0\\u589e\\u4ea7\\u54c1\\u6570\\uff1a\\u7cfb\\u7edf\\u4e2d\\u67d0\\u6708\\u65b0\\u589e\\u7684\\u4ea7\\u54c1\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":1820,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u7814\\u53d1\\u9700\\u6c42\\u6570\\uff1a\\u4ea7\\u54c1\\u4e2d\\u7814\\u53d1\\u9700\\u6c42\\u7684\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u521b\\u5efa\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u7814\\u53d1\\u9700\\u6c42\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u4ea4\\u4ed8\\u7814\\u53d1\\u9700\\u6c42\\u6570\\uff1a\\u4ea7\\u54c1\\u4e2d\\u7814\\u53d1\\u9700\\u6c42\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u6240\\u5904\\u9636\\u6bb5\\u4e3a\\u5df2\\u53d1\\u5e03\\u4e14\\u53d1\\u5e03\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\u6216\\u5173\\u95ed\\u539f\\u56e0\\u4e3a\\u5df2\\u5b8c\\u6210\\u4e14\\u5173\\u95ed\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u7814\\u53d1\\u9700\\u6c42\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":2356,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u7528\\u4f8b\\u6570\\uff1a\\u4ea7\\u54c1\\u4e2d\\u7528\\u4f8b\\u7684\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u521b\\u5efa\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u7528\\u4f8b\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u7528\\u4f8b\\u5e73\\u5747\\u0042\\u0075\\u0067\\u6570\\uff1a\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u7528\\u4f8b\\u6570\\u5173\\u8054\\u7684\\u0042\\u0075\\u0067\\u6570\\u002f\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u7528\\u4f8b\\u6570\\u3002\\u000A\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u0042\\u0075\\u0067\\u6570\\uff1a\\u4ea7\\u54c1\\u4e2d\\u0042\\u0075\\u0067\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u521b\\u5efa\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u0042\\u0075\\u0067\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u4fee\\u590d\\u0042\\u0075\\u0067\\u6570\\uff1a\\u4ea7\\u54c1\\u4e2d\\u0042\\u0075\\u0067\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u5173\\u95ed\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u89e3\\u51b3\\u65b9\\u6848\\u4e3a\\u5df2\\u89e3\\u51b3\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u0042\\u0075\\u0067\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u0062\\u0075\\u0067\\u5e73\\u5747\\u4fee\\u590d\\u65f6\\u95f4\\uff1a\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u4fee\\u590d\\u0042\\u0075\\u0067\\u7684\\u4fee\\u590d\\u5468\\u671f\\u002f\\u6309\\u4ea7\\u54c1\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u4fee\\u590d\\u0042\\u0075\\u0067\\u6570\\u3002\\u000A\\u4fee\\u590d\\u5468\\u671f\\uff1a\\u4fee\\u590d\\u65e5\\u671f\\u002d\\u521b\\u5efa\\u65e5\\u671f\\u3002\\u000A\\u4fee\\u590d\\uff1a\\u5df2\\u5173\\u95ed\\uff0c\\u5173\\u95ed\\u539f\\u56e0\\u4e3a\\u5df2\\u89e3\\u51b3\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":2872,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u5f53\\u524d\\u9879\\u76ee\\u6570\\uff1a\\u7cfb\\u7edf\\u4e2d\\u6240\\u6709\\u9879\\u76ee\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\u3002\\u000A\\u67d0\\u6708\\u6d3b\\u8dc3\\u9879\\u76ee\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u67d0\\u6708\\u6709\\u8fc7\\u52a8\\u6001\\u7684\\u9879\\u76ee\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\u3002\\u000A\\u67d0\\u6708\\u65b0\\u589e\\u9879\\u76ee\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u67d0\\u6708\\u65b0\\u589e\\u7684\\u9879\\u76ee\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":3278,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u6309\\u9879\\u76ee\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u7814\\u53d1\\u9700\\u6c42\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u7814\\u53d1\\u9700\\u6c42\\u7684\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u521b\\u5efa\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u7814\\u53d1\\u9700\\u6c42\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\\u000A\\u6309\\u9879\\u76ee\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u4ea4\\u4ed8\\u7814\\u53d1\\u9700\\u6c42\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u7814\\u53d1\\u9700\\u6c42\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u6240\\u5904\\u9636\\u6bb5\\u4e3a\\u5df2\\u53d1\\u5e03\\u4e14\\u53d1\\u5e03\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\u6216\\u5173\\u95ed\\u539f\\u56e0\\u4e3a\\u5df2\\u5b8c\\u6210\\u4e14\\u5173\\u95ed\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u7814\\u53d1\\u9700\\u6c42\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4ea7\\u54c1\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}},{\"id\":\"fc4u6zmi58w00\",\"isGroup\":false,\"attr\":{\"x\":1250,\"y\":3800,\"w\":20,\"h\":20,\"offsetX\":0,\"offsetY\":0,\"zIndex\":1},\"styles\":{\"filterShow\":false,\"hueRotate\":0,\"saturate\":1,\"contrast\":1,\"brightness\":1,\"opacity\":1,\"rotateZ\":0,\"rotateX\":0,\"rotateY\":0,\"skewX\":0,\"skewY\":0,\"blendMode\":\"normal\",\"animations\":[]},\"status\":{\"lock\":false,\"hide\":false},\"request\":{\"requestDataType\":0,\"requestHttpType\":\"get\",\"requestUrl\":\"\",\"requestInterval\":null,\"requestIntervalUnit\":\"second\",\"requestContentType\":0,\"requestParamsBodyType\":\"none\",\"requestSQLContent\":{\"sql\":\"select * from where\"},\"requestParams\":{\"Body\":{\"form-data\":{},\"x-www-form-urlencoded\":{},\"json\":\"\",\"xml\":\"\"},\"Header\":{},\"Params\":{}}},\"filter\":null,\"events\":{\"baseEvent\":{\"click\":null,\"dblclick\":null,\"mouseenter\":null,\"mouseleave\":null},\"advancedEvents\":{\"vnodeMounted\":null,\"vnodeBeforeMount\":null}},\"key\":\"Hint\",\"chartConfig\":{\"key\":\"Hint\",\"chartKey\":\"VHint\",\"conKey\":\"VCHint\",\"title\":\"\\u63d0\\u793a\",\"category\":\"Mores\",\"categoryName\":\"\\u66f4\\u591a\",\"package\":\"Informations\",\"chartFrame\":\"common\",\"image\":\"static\\/png\\/hint-2cbf6381.png\"},\"option\":{\"text\":\"\",\"icon\":\"\",\"textSize\":15,\"textColor\":\"#ffffff\",\"textWeight\":\"bold\",\"placement\":\"left-top\",\"distance\":8,\"hint\":\"\\u6309\\u9879\\u76ee\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u65b0\\u589e\\u4efb\\u52a1\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u4efb\\u52a1\\u7684\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u521b\\u5efa\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4efb\\u52a1\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\u3002\\u000A\\u6309\\u9879\\u76ee\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u8d21\\u732e\\u4efb\\u52a1\\u4eba\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u4efb\\u52a1\\u7684\\u521b\\u5efa\\u4eba\\u7684\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u521b\\u5efa\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4efb\\u52a1\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\uff0c\\u4eba\\u5458\\u53bb\\u91cd\\u3002\\u000A\\u6309\\u9879\\u76ee\\u7edf\\u8ba1\\u7684\\u6708\\u5ea6\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\\uff1a\\u9879\\u76ee\\u4e2d\\u4efb\\u52a1\\u4e2a\\u6570\\u6c42\\u548c\\uff0c\\u5b8c\\u6210\\u65f6\\u95f4\\u4e3a\\u67d0\\u5e74\\u67d0\\u6708\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u4efb\\u52a1\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u6267\\u884c\\u7684\\u4efb\\u52a1\\uff0c\\u8fc7\\u6ee4\\u5df2\\u5220\\u9664\\u7684\\u9879\\u76ee\\u3002\",\"width\":0,\"height\":0,\"paddingX\":16,\"paddingY\":8,\"borderWidth\":1,\"borderStyle\":\"solid\",\"borderColor\":\"#1a77a5\",\"borderRadius\":6,\"color\":\"#ffffff\",\"textAlign\":\"left\",\"fontWeight\":\"normal\",\"backgroundColor\":\"rgba(8, 40, 80, 0.9)\",\"fontSize\":16}}]', 'published', '1', 'admin', '2022-12-07 14:59:41', 'admin', '2022-12-07 14:59:41', '0'); ALTER TABLE `zt_project` ADD `division` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '1' AFTER `vision`; + +INSERT INTO `zt_config`(`vision`, `owner`, `module`, `section`, `key`, `value`) VALUES ('', 'system', 'common', 'global', 'installedDate', CURDATE()); From f2529dae806a9fffe0e4f3d0a3295025e9c8c325 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 16:15:19 +0800 Subject: [PATCH 071/235] * Change to new writing method. --- module/admin/ui/resetpwdsetting.html.php | 2 +- module/admin/ui/setmodule.html.php | 10 +++++----- module/task/ui/ajaxgetteststories.html.php | 18 +++++++++--------- module/task/ui/assignto.html.php | 2 +- module/task/ui/linearefforts.html.php | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/module/admin/ui/resetpwdsetting.html.php b/module/admin/ui/resetpwdsetting.html.php index e8ad970b6c..654ca6194e 100644 --- a/module/admin/ui/resetpwdsetting.html.php +++ b/module/admin/ui/resetpwdsetting.html.php @@ -51,7 +51,7 @@ if(common::hasPriv('admin', 'resetPWDSetting')) div ( - set::id('mainContent'), + setID('mainContent'), setClass('row has-sidebar-left'), $menuItems ? sidebar ( diff --git a/module/admin/ui/setmodule.html.php b/module/admin/ui/setmodule.html.php index 2be4ebba45..9af702809f 100644 --- a/module/admin/ui/setmodule.html.php +++ b/module/admin/ui/setmodule.html.php @@ -42,8 +42,8 @@ foreach($config->featureGroup as $group => $features) $items[] = checkbox ( + setID("module{$code}"), set::rootClass('w-40'), - set::id("module{$code}"), set::name("module[{$code}]"), set::value(1), set::checked($value == 1), @@ -53,8 +53,8 @@ foreach($config->featureGroup as $group => $features) $items[] = input ( + setID("module{$code}"), set::type('hidden'), - set::id("module{$code}"), set::name("module[{$code}]"), set::value($value) ); @@ -67,7 +67,7 @@ foreach($config->featureGroup as $group => $features) setClass('p-2.5'), checkbox ( - set::id("allChecker{$group}"), + setID("allChecker{$group}"), set::name("allChecker[$group]"), on::change('checkGroup'), $lang->admin->setModule->{$group} @@ -117,7 +117,7 @@ formPanel setClass('p-2.5'), checkbox ( - set::id('allCheckeer'), + setID('allCheckeer'), on::change('checkAll'), $lang->selectAll ) @@ -134,7 +134,7 @@ formPanel button ( setClass('btn open-url'), - set(array('data-back' => 'APP')), + setData(array('back' => 'APP')), $lang->goback ) ) diff --git a/module/task/ui/ajaxgetteststories.html.php b/module/task/ui/ajaxgetteststories.html.php index 6073086127..7755aa1920 100644 --- a/module/task/ui/ajaxgetteststories.html.php +++ b/module/task/ui/ajaxgetteststories.html.php @@ -26,7 +26,7 @@ foreach($testStories as $storyID => $storyTitle) ( picker ( - set::id("testStory{$i}"), + setID("testStory{$i}"), set::name("testStory[$i]"), set::value($storyID), set::items(array($storyID => $storyTitle)) @@ -36,7 +36,7 @@ foreach($testStories as $storyID => $storyTitle) ( picker ( - set::id("testPri{$i}"), + setID("testPri{$i}"), set::name("testPri[$i]"), set::required(true), set::value(empty($task->pri) ? 3 : $task->pri), @@ -47,7 +47,7 @@ foreach($testStories as $storyID => $storyTitle) ( datepicker ( - set::id("testEstStarted{$i}"), + setID("testEstStarted{$i}"), set::name("testEstStarted[$i]"), set::value(empty($task->estStarted) ? '' : $task->estStarted) ) @@ -56,7 +56,7 @@ foreach($testStories as $storyID => $storyTitle) ( datepicker ( - set::id("testDeadline{$i}"), + setID("testDeadline{$i}"), set::name("testDeadline[$i]"), set::value(empty($task->deadline) ? '' : $task->deadline) ) @@ -65,7 +65,7 @@ foreach($testStories as $storyID => $storyTitle) ( picker ( - set::id("testAssignedTo{$i}"), + setID("testAssignedTo{$i}"), set::name("testAssignedTo[$i]"), set::value(empty($task->assignedTo) ? '' : $task->assignedTo), set::items($members) @@ -77,7 +77,7 @@ foreach($testStories as $storyID => $storyTitle) ( input ( - set::id("testEstimate{$i}"), + setID("testEstimate{$i}"), set::name("testEstimate[$i]") ), to::suffix($lang->task->suffixHour), @@ -86,7 +86,7 @@ foreach($testStories as $storyID => $storyTitle) ), h::td ( - set::className('center'), + setClass('center'), btnGroup ( set::items(array( @@ -105,8 +105,8 @@ formGroup set::labelClass('selectStoryLabel'), h::table ( - set::className('table table-form'), - set::id('testTaskTable'), + setClass('table table-form'), + setID('testTaskTable'), h::thead ( h::tr diff --git a/module/task/ui/assignto.html.php b/module/task/ui/assignto.html.php index c3cb5dcd7b..4c4e809548 100644 --- a/module/task/ui/assignto.html.php +++ b/module/task/ui/assignto.html.php @@ -63,8 +63,8 @@ formPanel ( input ( + setID('left'), set::name('left'), - set::id('left'), set::value($task->left), set::type('text'), set::disabled(false) diff --git a/module/task/ui/linearefforts.html.php b/module/task/ui/linearefforts.html.php index 061dbb6bc3..83b0635126 100644 --- a/module/task/ui/linearefforts.html.php +++ b/module/task/ui/linearefforts.html.php @@ -75,7 +75,7 @@ foreach($myCountList as $order => $count) common::hasPriv('task', 'deleteWorkhour') ? a ( setClass('btn ghost toolbar-item square size-sm ajax-submit'), - set('data-confirm', $lang->task->confirmDeleteEffort), + setData(array('confirm' => $lang->task->confirmDeleteEffort)), set::href(createLink('task', 'deleteWorkhour', "id={$effort->id}")), icon('trash') ) : null @@ -108,7 +108,7 @@ foreach($recorders as $order => $accounts) div ( - set::id('linearefforts'), + setID('linearefforts'), tabs ( tabPane From cdc9d3adcd40b81c281be23c5cc2d0c4fd7f30c3 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Thu, 16 Nov 2023 16:23:08 +0800 Subject: [PATCH 072/235] * Count parent column cards. --- module/kanban/model.php | 45 ++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/module/kanban/model.php b/module/kanban/model.php index 66772f9623..5035f028c4 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1712,9 +1712,9 @@ class kanbanModel extends model */ public function buildExecutionGroup(object $lane, array $columns, array $objectGroup, string $searchValue = '', array $menus = array()): array { - $laneData = array(); - $columnData = array(); - $cardsData = array(); + $laneData = array(); + $columnsData = array(); + $cardsData = array(); $laneData['id'] = $lane->id; $laneData['type'] = $lane->type; @@ -1727,28 +1727,32 @@ class kanbanModel extends model { $cardIdList = array_unique(array_filter(explode(',', $column->cards))); - $columnData[$column->id]['id'] = $columnID; - $columnData[$column->id]['type'] = $column->type; - $columnData[$column->id]['name'] = $columnID; - $columnData[$column->id]['title'] = $column->name; - $columnData[$column->id]['color'] = $column->color; - $columnData[$column->id]['limit'] = $column->limit; - $columnData[$column->id]['region'] = $lane->region; - $columnData[$column->id]['laneName'] = $column->lane; - $columnData[$column->id]['group'] = $lane->type; - $columnData[$column->id]['parent'] = $column->parent; - $columnData[$column->id]['cards'] = 0; - $columnData[$column->id]['actionList'] = array('setColumn', 'setWIP'); + $columnsData[$column->id]['id'] = $columnID; + $columnsData[$column->id]['type'] = $column->type; + $columnsData[$column->id]['name'] = $columnID; + $columnsData[$column->id]['title'] = $column->name; + $columnsData[$column->id]['color'] = $column->color; + $columnsData[$column->id]['limit'] = $column->limit; + $columnsData[$column->id]['region'] = $lane->region; + $columnsData[$column->id]['laneName'] = $column->lane; + $columnsData[$column->id]['group'] = $lane->type; + $columnsData[$column->id]['cards'] = 0; + $columnsData[$column->id]['actionList'] = array('setColumn', 'setWIP'); - if($column->parent > 0) $columnData[$column->id]['parentName'] = $column->parent; + if($column->parent > 0) $columnsData[$column->id]['parentName'] = $column->parent; if($cardIdList) { $cardsData = $this->buildExecutionCards($cardsData, $column, $lane->type, $cardIdList, $objectGroup, $searchValue, $menus); - $columnData[$column->id]['cards'] = count($cardsData[$column->lane][$column->id]); + $columnsData[$column->id]['cards'] = count($cardsData[$column->lane][$column->id]); } } - return array($laneData, array_values($columnData), $cardsData); + foreach($columnsData as $columnData) + { + if(isset($columnData['parentName'])) $columnsData[$columnData['parentName']]['cards'] += $columnData['cards']; + } + + return array($laneData, array_values($columnsData), $cardsData); } /** @@ -1988,6 +1992,11 @@ class kanbanModel extends model $lanesData[] = $laneData; } + foreach($columnsData as $columnData) + { + if(isset($columnData['parentName'])) $columnsData[$columnData['parentName']]['cards'] += $columnData['cards']; + } + $kanbanGroup['id'] = $executionID; $kanbanGroup['key'] = 'group' . $executionID; $kanbanGroup['data'] = array(); From 606d393f9b2c929a663bcbff5e8c46a0d0db8dca Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Thu, 16 Nov 2023 16:24:30 +0800 Subject: [PATCH 073/235] * Fix the bug of doclib empty. --- module/doc/ui/tablecontents.html.php | 34 +++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/module/doc/ui/tablecontents.html.php b/module/doc/ui/tablecontents.html.php index 8008de03bb..af12939d05 100644 --- a/module/doc/ui/tablecontents.html.php +++ b/module/doc/ui/tablecontents.html.php @@ -9,6 +9,31 @@ declare(strict_types=1); * @link https://www.zentao.net */ namespace zin; + +$createLibButton = common::hasPriv('doc', 'createLib') ? btn +( + setClass('secondary'), + set::icon('plus'), + set::url(createLink('doc', 'createLib', "type={$type}&objectID={$objectID}")), + setData('toggle', 'modal'), + $lang->doc->createLib +) : null; + +if(empty($libTree)) +{ + featureBar(); + toolbar($createLibButton); + dtable( + set::cols(array()), + set::data(array()), + set::createLink(createLink('doc', 'createLib', "type={$type}&objectID={$objectID}")), + set::createTip($lang->doc->createLib), + set::createAttr("data-toggle='modal'"), + set::emptyTip($lang->doc->noLib) + ); + return; +} + if(!empty($libTree)) include 'lefttree.html.php'; if($libType != 'api' && $libID && common::hasPriv('doc', 'create')) include 'createbutton.html.php'; @@ -62,14 +87,7 @@ toolbar 'url' => $exportLink, 'data-toggle' => 'modal' ))) : null, - common::hasPriv('doc', 'createLib') ? item(set(array - ( - 'icon' => 'plus', - 'class' => 'btn secondary', - 'text' => $lang->doc->createLib, - 'url' => createLink('doc', 'createLib', "type={$type}&objectID={$objectID}"), - 'data-toggle' => 'modal' - ))) : null, + $createLibButton, $libType == 'api' && common::hasPriv('api', 'create') ? item(set(array ( 'icon' => 'plus', From c19cd24287f955bf16e9a583d3ed4d7f740608ba Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 08:30:11 +0000 Subject: [PATCH 074/235] * Add pager on feature bar. * Adjust toolbar. --- module/stakeholder/ui/browse.html.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/module/stakeholder/ui/browse.html.php b/module/stakeholder/ui/browse.html.php index f85b0c507c..b3551d1240 100644 --- a/module/stakeholder/ui/browse.html.php +++ b/module/stakeholder/ui/browse.html.php @@ -31,34 +31,41 @@ featureBar set::className('nav-item'), a ( - set::href($this->createLink('stakeholder', 'browse', $navLinkParams)), + setClass('active'), + set::href($this->createLink('stakeholder', 'browse', "project=$projectID&browseType={$browseType}&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}")), set('data-app', $app->tab), $lang->stakeholder->browse ) - ), - set::current('all') + ) ); /* Toolbar. */ -$createLink = $this->createLink('stakeholder', 'create', "projectID=$projectID"); -$batchCreateLink = $this->createLink('stakeholder', 'batchCreate', "projectID=$projectID"); -$createItem = array('text' => $lang->stakeholder->create, 'url' => $createLink, 'data-app' => 'project'); -$batchCreateItem = array('text' => $lang->stakeholder->batchCreate, 'url' => $batchCreateLink); +$canCreate = hasPriv('stakeholder', 'create'); +$canBatchCreate = hasPriv('stakeholder', 'batchcreate'); -if(common::hasPriv('stakeholder', 'batchcreate') and common::hasPriv('stakeholder', 'create')) +if($canCreate || $canBatchCreate) { + $createLink = $this->createLink('stakeholder', 'create', "projectID=$projectID"); + $batchCreateLink = $this->createLink('stakeholder', 'batchCreate', "projectID=$projectID"); + $items = array(); + if($canCreate) $items[] = array('text' => $lang->stakeholder->create, 'url' => $createLink, 'data-app' => 'project'); + if($canBatchCreate) $items[] = array('text' => $lang->stakeholder->batchCreate, 'url' => $batchCreateLink); toolbar ( - btngroup + count($items) > 1 ? btngroup ( btn(setClass('btn primary'), setData(array('app' => 'project')), set::icon('plus'), set::url($createLink), $lang->stakeholder->create), dropdown ( btn(setClass('btn primary dropdown-toggle'), setStyle(array('padding' => '6px', 'border-radius' => '0 2px 2px 0'))), - set::items(array_filter(array($createItem, $batchCreateItem))), + set::items($items), set::placement('bottom-end') ) + ) : btn + ( + setClass('btn primary'), + set(reset($items)) ) ); } From b8d5977c1df653719b7b735d644c403e12b0768b Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 08:39:05 +0000 Subject: [PATCH 075/235] * Use html for editor. --- module/stakeholder/ui/edit.html.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/module/stakeholder/ui/edit.html.php b/module/stakeholder/ui/edit.html.php index 3d86f980f8..6520a2ae6c 100644 --- a/module/stakeholder/ui/edit.html.php +++ b/module/stakeholder/ui/edit.html.php @@ -73,24 +73,30 @@ formPanel ( set::width('full'), set::label($lang->stakeholder->nature), - set::name('nature'), - set::control('editor'), - set::value($stakeholder->nature) + editor + ( + set::name('nature'), + html($stakeholder->nature) + ) ), formGroup ( set::width('full'), set::label($lang->stakeholder->analysis), - set::name('analysis'), - set::control('editor'), - set::value($stakeholder->analysis) + editor + ( + set::name('analysis'), + html($stakeholder->analysis) + ) ), formGroup ( set::width('full'), set::label($lang->stakeholder->strategy), - set::name('strategy'), - set::control('editor'), - set::value($stakeholder->strategy) + editor + ( + set::name('strategy'), + html($stakeholder->strategy) + ) ) ); From c61e4fc501340d4a320d5e3ce0e3223e8cb4efcf Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Thu, 16 Nov 2023 17:03:36 +0800 Subject: [PATCH 076/235] * Change to new writing method. --- module/task/ui/batchcreate.html.php | 34 +++++++++++++++++++---------- module/task/ui/create.html.php | 4 ++-- module/task/ui/edit.html.php | 22 +++++++++---------- module/task/ui/pause.html.php | 4 ++-- module/task/ui/report.html.php | 8 +++---- module/task/ui/view.html.php | 25 +++++++++++++++------ 6 files changed, 59 insertions(+), 38 deletions(-) diff --git a/module/task/ui/batchcreate.html.php b/module/task/ui/batchcreate.html.php index 326dec4b6c..6f197812da 100644 --- a/module/task/ui/batchcreate.html.php +++ b/module/task/ui/batchcreate.html.php @@ -39,13 +39,18 @@ if(!$hideStory) set::control('hidden'), btn ( - set('type', 'btn'), - set('icon', 'eye'), - set('class', 'ghost'), - set('hint', $lang->preview), - set('data-url', '#'), - set('data-toggle', 'modal'), - set('disabled', true) + set( + array + ( + 'type' => 'btn', + 'icon' => 'eye', + 'class' => 'ghost', + 'hint' => $lang->preview, + 'data-url' => '#', + 'data-toggle' => 'modal', + 'disabled' => true + ) + ) ) ); @@ -57,10 +62,15 @@ if(!$hideStory) set::control('hidden'), btn ( - set('type', 'btn'), - set('icon', 'arrow-right'), - set('class', 'ghost'), - set('hint', $lang->task->copyStoryTitle) + set( + array + ( + 'type' => 'btn', + 'icon' => 'copy', + 'class' => 'ghost', + 'hint' => $lang->task->copyStoryTitle + ) + ) ) ); @@ -222,7 +232,7 @@ formBatchPanel ( checkbox ( - set::id('zeroTaskStory'), + setID('zeroTaskStory'), set::text($lang->story->zeroTask), on::change('toggleZeroTaskStory') ) diff --git a/module/task/ui/create.html.php b/module/task/ui/create.html.php index 6f73350ba6..0b06b42a34 100644 --- a/module/task/ui/create.html.php +++ b/module/task/ui/create.html.php @@ -221,11 +221,11 @@ formPanel $from == 'task' ? set::customFields(true) : null, modal ( - set::id('modalTeam'), + setID('modalTeam'), set::title($lang->task->teamMember), h::table ( - set::id('teamTable'), + setID('teamTable'), h::tr ( h::td diff --git a/module/task/ui/edit.html.php b/module/task/ui/edit.html.php index bebf1e0093..c7008f432e 100644 --- a/module/task/ui/edit.html.php +++ b/module/task/ui/edit.html.php @@ -181,8 +181,8 @@ detailBody ( setClass('flex'), checkbox( - set::rootClass('items-center ml-3'), setID('showAllModule'), + set::rootClass('items-center ml-3'), set::name('showAllModule'), set::text($lang->all), set::value(1), @@ -309,31 +309,31 @@ detailBody ), span ( - set('id', 'contactBox'), - set('class', 'input-group-addon'), + setID('contactBox'), + setClass('input-group-addon'), $contactListMenuOptions ? setStyle(array('width' => '100px', 'padding' => '0')) : null, $contactListMenuOptions ? picker ( - set::className('width', 'w-20'), + setClass('w-20'), set::name('contactListMenuOptionsMenu'), set::items($contactListMenuOptions), set::placeholder($lang->contact->common) ) : span ( - set('class', 'input-group-addon'), + setClass('input-group-addon'), a ( - set('class', 'mr-2'), set('href', createLink('my', 'managecontacts', 'listID=0&mode=new')), set('title', $lang->user->contacts->manage), - set('data-toggle', 'modal'), + setClass('mr-2'), + setData(array('toggle' => 'modal')), icon('cog'), ), a ( - set('id', 'refreshMailto'), - set('class', 'text-black'), + setID('refreshMailto'), + setClass('text-black'), set('href', 'javascript:void(0)'), icon('refresh') ) @@ -346,7 +346,7 @@ detailBody ( modal ( - set::id('modalTeam'), + setID('modalTeam'), set::title($lang->task->teamMember), h::table ( @@ -415,7 +415,7 @@ detailBody span ( setClass('span-text'), - set::id('consumedSpan'), + setID('consumedSpan'), $task->consumed . $lang->task->suffixHour ), btn diff --git a/module/task/ui/pause.html.php b/module/task/ui/pause.html.php index f8b5dc533c..37836716a0 100644 --- a/module/task/ui/pause.html.php +++ b/module/task/ui/pause.html.php @@ -17,7 +17,7 @@ namespace zin; modalHeader(); formPanel ( - set::id('taskPauseForm'), + setID('taskPauseForm'), formGroup ( set::label($lang->comment), @@ -27,7 +27,7 @@ formPanel set::rows('5') ), input( - set::className('hidden'), + setClass('hidden'), set::name('status'), set::value('pause') ) diff --git a/module/task/ui/report.html.php b/module/task/ui/report.html.php index 810d37f32f..2abbf50832 100644 --- a/module/task/ui/report.html.php +++ b/module/task/ui/report.html.php @@ -66,8 +66,8 @@ foreach($lang->report->typeList as $type => $typeName) to::prefix(icon($type == 'default' ? 'list-alt' : "chart-{$type}")), div ( - set::className('pb-4'), - span(set::className('text-gray'), + setClass('pb-4'), + span(setClass('text-gray'), html(str_replace('%tab%', $lang->task->waitTask . $lang->testcase->common, $lang->report->notice->help))) ), div($echarts) @@ -83,7 +83,7 @@ div formPanel ( setClass('chart-form'), - set::id('chartForm'), + setID('chartForm'), set::title($lang->task->report->select), set::actionsClass('justify-start'), set::actions @@ -119,7 +119,7 @@ div ( setID('chartContainer'), set::flex('1'), - set::className('ml-5 bg-white px-4 py-2'), + setClass('ml-5 bg-white px-4 py-2'), tabs ( on::click('.font-medium', 'changeTab'), diff --git a/module/task/ui/view.html.php b/module/task/ui/view.html.php index 6bb32b7a7a..bdfef66598 100644 --- a/module/task/ui/view.html.php +++ b/module/task/ui/view.html.php @@ -149,7 +149,7 @@ foreach($linkMRTitles as $MRID => $linkMRTitle) ( set::href(createLink('mr', 'view', "MRID=$MRID")), "#$MRID $linkMRTitle", - set('data-ap', $app->tab) + setData(array('ap' => $app->tab)) ) : div("#$MRID $linkMRTitle"); } @@ -162,7 +162,7 @@ foreach($linkCommits as $commit) ( set::href(createLink('repo', 'revision', "repoID={$commit->repo}&objectID={$task->execution}&revision={$commit->revision}")), "#$MRID $linkMRTitle", - set('data-ap', $app->tab) + setData(array('ap' => $app->tab)) ) : div($revision . ' ' . $commit->comment); } @@ -273,8 +273,13 @@ detailBody set::name($lang->task->story), a ( - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setData( + array + ( + 'toggle' => 'modal', + 'size' => 'lg' + ) + ), set::href(createLink('story', 'view', "id={$task->story}")), set::title($task->storyTitle), $task->storyTitle @@ -285,8 +290,14 @@ detailBody set::name($lang->task->fromBug), !empty($fromBug) ? a ( - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setData + ( + array + ( + 'toggle' => 'modal', + 'size' => 'lg' + ) + ), set::href(createLink('bug', 'view', "id={$task->fromBug}")), set::title($fromBug->title), $fromBug->title @@ -364,7 +375,7 @@ detailBody h::table ( setClass('table table-data'), - set::id('team'), + setID('team'), h::thead ( h::tr From 5c616cca53ec9e25cb1312dd7e904f5ed6ac7da1 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 17:05:54 +0800 Subject: [PATCH 077/235] + Add tooltips to product statistic block. --- module/block/lang/zh-cn.php | 5 +++ .../block/ui/productstatisticblock.html.php | 39 +++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index a3b6f2ee36..c275127102 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -703,3 +703,8 @@ $lang->block->moduleList['teamachievement'] = $lang->block->teamAchievement; $lang->block->moduleList['assigntome'] = $lang->block->assignToMe; $lang->block->moduleList['dynamic'] = $lang->block->dynamic; $lang->block->moduleList['html'] = $lang->block->html; + +$lang->block->tooltips = array(); +$lang->block->tooltips['deliveryRate'] = '需求交付率=按产品统计的已交付研发需求数/(按产品统计的研发需求总数-按产品统计的无效研发需求数)*100%'; +$lang->block->tooltips['effectiveStory'] = '按产品统计的研发需求总数:产品中研发需求的个数求和,过滤已删除的研发需求,过滤已删除的产品。'; +$lang->block->tooltips['deliveredStory'] = '按产品统计的已交付研发需求数:产品中研发需求个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的研发需求,过滤已删除的产品。'; diff --git a/module/block/ui/productstatisticblock.html.php b/module/block/ui/productstatisticblock.html.php index cde9524469..7ae5090390 100644 --- a/module/block/ui/productstatisticblock.html.php +++ b/module/block/ui/productstatisticblock.html.php @@ -78,7 +78,20 @@ statisticBlock ( setClass('row text-sm text-gray items-center gap-1'), $lang->block->productstatistic->deliveryRate, - icon('help text-light text-sm') + icon + ( + 'help', + toggle::tooltip + ( + array + ( + 'title' => $lang->block->tooltip['deliveryRate'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ) + ) ) ), row @@ -99,7 +112,17 @@ statisticBlock span ( setClass('text-sm text-gray'), - $lang->block->productstatistic->effectiveStory + $lang->block->productstatistic->effectiveStory, + toggle::tooltip + ( + array + ( + 'title' => $lang->block->tooltip['effectiveStory'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ) ) ) ), @@ -118,7 +141,17 @@ statisticBlock span ( setClass('text-sm text-gray'), - $lang->block->productstatistic->delivered + $lang->block->productstatistic->delivered, + toggle::tooltip + ( + array + ( + 'title' => $lang->block->tooltip['deliveredStory'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ) ) ) ), From 57a7eb0a38d6cee6f6dc0147fa8cdcc7852d307c Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 09:14:34 +0000 Subject: [PATCH 078/235] * Format codes. --- module/stakeholder/ui/browse.html.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/module/stakeholder/ui/browse.html.php b/module/stakeholder/ui/browse.html.php index b3551d1240..960ea89bf9 100644 --- a/module/stakeholder/ui/browse.html.php +++ b/module/stakeholder/ui/browse.html.php @@ -40,16 +40,18 @@ featureBar ); /* Toolbar. */ -$canCreate = hasPriv('stakeholder', 'create'); -$canBatchCreate = hasPriv('stakeholder', 'batchcreate'); +$canCreate = hasPriv('stakeholder', 'create'); +$canBatchCreate = hasPriv('stakeholder', 'batchcreate'); if($canCreate || $canBatchCreate) { $createLink = $this->createLink('stakeholder', 'create', "projectID=$projectID"); $batchCreateLink = $this->createLink('stakeholder', 'batchCreate', "projectID=$projectID"); + $items = array(); if($canCreate) $items[] = array('text' => $lang->stakeholder->create, 'url' => $createLink, 'data-app' => 'project'); if($canBatchCreate) $items[] = array('text' => $lang->stakeholder->batchCreate, 'url' => $batchCreateLink); + toolbar ( count($items) > 1 ? btngroup From 610db1ae2bd18fde05a297dd4da0dc3537403c3e Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 09:15:01 +0000 Subject: [PATCH 079/235] * Set objectID for dropmenu. --- module/stakeholder/control.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/module/stakeholder/control.php b/module/stakeholder/control.php index fdf3110614..ec76e58cc1 100644 --- a/module/stakeholder/control.php +++ b/module/stakeholder/control.php @@ -179,11 +179,13 @@ class stakeholder extends control $users = array_diff($users, $members); } - $this->view->title = $this->lang->stakeholder->edit; + if($stakeholder->objectType == 'project') $this->view->projectID = $stakeholder->objectID; + $this->view->title = $this->lang->stakeholder->edit; $this->view->stakeholder = $stakeholder; $this->view->users = $users; $this->view->companys = $this->loadModel('company')->getOutsideCompanies(); + $this->display(); } @@ -360,6 +362,8 @@ class stakeholder extends control $this->loadModel('project')->setMenu($user->objectID); $this->commonAction($userID, 'stakeholder'); + if($user->objectType == 'project') $this->view->projectID = $user->objectID; + $this->view->title = $this->lang->stakeholder->common . $this->lang->colon . $this->lang->stakeholder->view; $this->view->user = $user; $this->view->users = $this->loadModel('user')->getTeamMemberPairs($this->session->project, 'project', 'nodeleted'); From fec0e910e56339eba499cdd793399bbc720ccb32 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Thu, 16 Nov 2023 17:15:44 +0800 Subject: [PATCH 080/235] * Optimize code for product statistic block. --- module/block/ui/productstatisticblock.html.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/module/block/ui/productstatisticblock.html.php b/module/block/ui/productstatisticblock.html.php index 7ae5090390..66a538cc5b 100644 --- a/module/block/ui/productstatisticblock.html.php +++ b/module/block/ui/productstatisticblock.html.php @@ -85,9 +85,9 @@ statisticBlock ( array ( - 'title' => $lang->block->tooltip['deliveryRate'], + 'title' => $lang->block->tooltips['deliveryRate'], 'placement' => 'bottom', - 'type' => 'white', + 'type' => 'white', 'className' => 'text-dark border border-light leading-5' ) ) @@ -117,9 +117,9 @@ statisticBlock ( array ( - 'title' => $lang->block->tooltip['effectiveStory'], + 'title' => $lang->block->tooltips['effectiveStory'], 'placement' => 'bottom', - 'type' => 'white', + 'type' => 'white', 'className' => 'text-dark border border-light leading-5' ) ) @@ -146,9 +146,9 @@ statisticBlock ( array ( - 'title' => $lang->block->tooltip['deliveredStory'], + 'title' => $lang->block->tooltips['deliveredStory'], 'placement' => 'bottom', - 'type' => 'white', + 'type' => 'white', 'className' => 'text-dark border border-light leading-5' ) ) From 2e912e91efe4613cbc8b5edcb8592677ed81d619 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 17:16:20 +0800 Subject: [PATCH 081/235] * project: stop compute end date if the period radios didn't be checked. --- module/project/js/common.ui.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index baea0d2259..d8c6d5dad6 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -119,7 +119,9 @@ function computeEndDate() const beginDate = $('#begin').zui('datePicker').$.state.value; if(!beginDate) return; - const delta = parseInt($('input[name=delta]:checked').val()); + const delta = parseInt($('input[name=delta]:checked').val()); + if(isNaN(delta)) return; + const isLongTime = delta == 999; const endDate = isLongTime ? LONG_TIME : formatDate(beginDate, delta - 1); From 03e29c398afaecbe6a4f138ee021be7667f90572 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 16 Nov 2023 17:18:03 +0800 Subject: [PATCH 082/235] * Adjust devops menu display rule. --- module/admin/lang/menu.php | 58 +++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/module/admin/lang/menu.php b/module/admin/lang/menu.php index 8771c3a148..b4f4227b66 100644 --- a/module/admin/lang/menu.php +++ b/module/admin/lang/menu.php @@ -44,9 +44,12 @@ $lang->admin->menuList->convert['desc'] = $lang->admin->menuSetting['convert'][ $lang->admin->menuList->convert['link'] = 'convert|convertjira'; $lang->admin->menuList->convert['order'] = 50; -$lang->admin->menuList->platform['name'] = $lang->admin->menuSetting['platform']['name']; -$lang->admin->menuList->platform['desc'] = $lang->admin->menuSetting['platform']['desc']; -$lang->admin->menuList->platform['order'] = 55; +if(helper::hasFeature('devops')) +{ + $lang->admin->menuList->platform['name'] = $lang->admin->menuSetting['platform']['name']; + $lang->admin->menuList->platform['desc'] = $lang->admin->menuSetting['platform']['desc']; + $lang->admin->menuList->platform['order'] = 55; +} $lang->admin->menuList->system['subMenu']['mode'] = array('link' => "{$lang->custom->mode}|custom|mode|"); $lang->admin->menuList->system['subMenu']['trash'] = array('link' => "{$lang->action->trash}|action|trash|"); @@ -181,32 +184,35 @@ $lang->admin->menuList->dev['menuOrder']['15'] = 'langItem'; $lang->admin->menuList->dev['menuOrder']['20'] = 'editor'; $lang->admin->menuList->dev['menuOrder']['25'] = 'entry'; -//$lang->admin->menuList->platform['subMenu']['environment'] = array('link' => "{$lang->devops->environment}|gitlab|browse|", 'subModule' => 'gitlab,jenkins,sonarqube,gitea,gogs', 'alias' => 'create,edit,import'); -$lang->admin->menuList->platform['subMenu']['resource'] = array('link' => "{$lang->devops->resource}|host|browse|", 'subModule' => 'host,account,serverroom,ops,tree'); -$lang->admin->menuList->platform['subMenu']['setrules'] = array('link' => "{$lang->devops->rules}|repo|setrules|"); +if(helper::hasFeature('devops')) +{ + //$lang->admin->menuList->platform['subMenu']['environment'] = array('link' => "{$lang->devops->environment}|gitlab|browse|", 'subModule' => 'gitlab,jenkins,sonarqube,gitea,gogs', 'alias' => 'create,edit,import'); + $lang->admin->menuList->platform['subMenu']['resource'] = array('link' => "{$lang->devops->resource}|host|browse|", 'subModule' => 'host,account,serverroom,ops,tree'); + $lang->admin->menuList->platform['subMenu']['setrules'] = array('link' => "{$lang->devops->rules}|repo|setrules|"); -$lang->admin->menuList->platform['tabMenu']['resource']['host'] = array('link' => "{$lang->devops->host}|host|browse|", 'alias' => 'create,edit,view,treemap,changestatus,group', 'subModule' => 'tree'); -$lang->admin->menuList->platform['tabMenu']['resource']['serverroom'] = array('link' => "{$lang->devops->serverroom}|serverroom|browse|", 'alias' => 'create,edit,view'); -$lang->admin->menuList->platform['tabMenu']['resource']['account'] = array('link' => "{$lang->devops->account}|account|browse|", 'alias' => 'create,edit,view'); -$lang->admin->menuList->platform['tabMenu']['resource']['provider'] = array('link' => "{$lang->devops->provider}|ops|provider|", 'alias' => 'provider'); -$lang->admin->menuList->platform['tabMenu']['resource']['city'] = array('link' => "{$lang->devops->city}|ops|city|", 'alias' => 'city'); -$lang->admin->menuList->platform['tabMenu']['resource']['cpuBrand'] = array('link' => "{$lang->devops->cpuBrand}|ops|cpuBrand|", 'alias' => 'cpubrand'); -$lang->admin->menuList->platform['tabMenu']['resource']['os'] = array('link' => "{$lang->devops->os}|ops|os|", 'alias' => 'os'); + $lang->admin->menuList->platform['tabMenu']['resource']['host'] = array('link' => "{$lang->devops->host}|host|browse|", 'alias' => 'create,edit,view,treemap,changestatus,group', 'subModule' => 'tree'); + $lang->admin->menuList->platform['tabMenu']['resource']['serverroom'] = array('link' => "{$lang->devops->serverroom}|serverroom|browse|", 'alias' => 'create,edit,view'); + $lang->admin->menuList->platform['tabMenu']['resource']['account'] = array('link' => "{$lang->devops->account}|account|browse|", 'alias' => 'create,edit,view'); + $lang->admin->menuList->platform['tabMenu']['resource']['provider'] = array('link' => "{$lang->devops->provider}|ops|provider|", 'alias' => 'provider'); + $lang->admin->menuList->platform['tabMenu']['resource']['city'] = array('link' => "{$lang->devops->city}|ops|city|", 'alias' => 'city'); + $lang->admin->menuList->platform['tabMenu']['resource']['cpuBrand'] = array('link' => "{$lang->devops->cpuBrand}|ops|cpuBrand|", 'alias' => 'cpubrand'); + $lang->admin->menuList->platform['tabMenu']['resource']['os'] = array('link' => "{$lang->devops->os}|ops|os|", 'alias' => 'os'); -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['5'] = 'host'; -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['10'] = 'serverroom'; -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['15'] = 'account'; -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['20'] = 'provider'; -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['25'] = 'city'; -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['30'] = 'cpuBrand'; -$lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['35'] = 'os'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['5'] = 'host'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['10'] = 'serverroom'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['15'] = 'account'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['20'] = 'provider'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['25'] = 'city'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['30'] = 'cpuBrand'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['35'] = 'os'; -//$lang->admin->menuList->platform['menuOrder']['5'] = 'dashboard'; -//$lang->admin->menuList->platform['menuOrder']['15'] = 'environment'; -$lang->admin->menuList->platform['menuOrder']['20'] = 'resource'; -$lang->admin->menuList->platform['menuOrder']['25'] = 'setrules'; + //$lang->admin->menuList->platform['menuOrder']['5'] = 'dashboard'; + //$lang->admin->menuList->platform['menuOrder']['15'] = 'environment'; + $lang->admin->menuList->platform['menuOrder']['20'] = 'resource'; + $lang->admin->menuList->platform['menuOrder']['25'] = 'setrules'; -$lang->admin->menuList->platform['dividerMenu'] = ',plat,setrules,'; + $lang->admin->menuList->platform['dividerMenu'] = ',plat,setrules,'; +} if($config->edition != 'max' and $config->edition != 'ipd') { @@ -272,7 +278,7 @@ if($config->vision == 'lite') $lang->admin->menuList->feature['menuOrder']['15'] = 'project'; } -if($config->inQuickon) +if($config->inQuickon && helper::hasFeature('devops')) { $lang->admin->menuList->platform['subMenu']['dashboard'] = array('link' => "{$lang->dashboard}|system|dashboard|"); $lang->admin->menuList->platform['menuOrder']['5'] = 'dashboard'; From 42102a015c3bb1a88f2eda7b69f2e9171d72e0ef Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 17:18:29 +0800 Subject: [PATCH 083/235] + project: add configuration item of the days column in batch edit page. --- module/project/config/form.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/project/config/form.php b/module/project/config/form.php index 07934d736f..d3e0715ffd 100644 --- a/module/project/config/form.php +++ b/module/project/config/form.php @@ -49,6 +49,7 @@ $config->project->form->batchedit['name'] = array('type' => 'string', 'requir $config->project->form->batchedit['PM'] = array('type' => 'string', 'required' => false); $config->project->form->batchedit['begin'] = array('type' => 'date', 'required' => true); $config->project->form->batchedit['end'] = array('type' => 'date', 'required' => true); +$config->project->form->batchedit['day'] = array('type' => 'int', 'required' => false); $config->project->form->batchedit['acl'] = array('type' => 'string', 'required' => false); if(isset($config->setCode) and $config->setCode == 1) $config->project->form->batchedit['code'] = array('type' => 'string', 'required' => true, 'filter' => 'trim'); From 7935812eb9ddb85f09b1bbd848e13020ef0f6a9e Mon Sep 17 00:00:00 2001 From: daitingting Date: Thu, 16 Nov 2023 09:24:01 +0000 Subject: [PATCH 084/235] * Format codes. --- module/stakeholder/ui/expect.html.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/module/stakeholder/ui/expect.html.php b/module/stakeholder/ui/expect.html.php index 05488e4ce4..c718640e11 100644 --- a/module/stakeholder/ui/expect.html.php +++ b/module/stakeholder/ui/expect.html.php @@ -17,13 +17,19 @@ formPanel formGroup ( set::label($lang->stakeholder->expect), - set::name('expect'), - set::control('editor') + editor + ( + set::name('expect'), + set::rows(5) + ) ), formGroup ( set::label($lang->stakeholder->progress), - set::name('progress'), - set::control('editor') + editor + ( + set::name('progress'), + set::rows(5) + ) ) ); From bc751d458bfe53af52b4f23536f264a496224312 Mon Sep 17 00:00:00 2001 From: liugang Date: Thu, 16 Nov 2023 17:24:50 +0800 Subject: [PATCH 085/235] * project: change the project to long term project if the end date is greater than or equal to the const LONG_TIME. --- module/project/js/common.ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index d8c6d5dad6..d308cc30cf 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -87,10 +87,10 @@ function computeWorkDays() const begin = $('#begin').zui('datePicker').$.state.value; const end = $('#end').zui('datePicker').$.state.value; - if(end == LONG_TIME) + if(end >= LONG_TIME) { $('#delta999').prop('checked', true); - $('#days').val(0).trigger('change'); + computeEndDate(); } else { From d2f8759ca6883eed89db1e35bcc0c90bb2045da5 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Fri, 17 Nov 2023 08:24:21 +0800 Subject: [PATCH 086/235] * Update file tree build rule for repo. --- lib/zin/wg/treeeditor/v1.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/zin/wg/treeeditor/v1.php b/lib/zin/wg/treeeditor/v1.php index a564f56491..417446a37a 100644 --- a/lib/zin/wg/treeeditor/v1.php +++ b/lib/zin/wg/treeeditor/v1.php @@ -35,11 +35,10 @@ class treeEditor extends wg private function buildTree(array $items): array { - $canUpdateOrder = $this->prop('canUpdateOrder'); - $canEdit = $this->prop('canEdit'); - $canDelete = $this->prop('canDelete'); - $canSplit = $this->prop('canSplit'); - $editType = $this->prop('type'); + $canEdit = $this->prop('canEdit'); + $canDelete = $this->prop('canDelete'); + $canSplit = $this->prop('canSplit'); + $editType = $this->prop('type'); foreach($items as $key => $item) { @@ -66,7 +65,7 @@ class treeEditor extends wg if(!empty($item['children'])) { - $item['items'] = $this->buildTree($item['children']); + $item['items'] = !empty($item['children']['url']) ? $item['children'] : $this->buildTree($item['children']); unset($item['children']); } unset($item['type']); From 8d208d03ce43940dcdbfc7acad03899facb056be Mon Sep 17 00:00:00 2001 From: sunguangming Date: Fri, 17 Nov 2023 08:53:06 +0800 Subject: [PATCH 087/235] * Fix kanban code error. --- extension/lite/kanban/ext/model/lite.php | 4 ++-- module/kanban/model.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extension/lite/kanban/ext/model/lite.php b/extension/lite/kanban/ext/model/lite.php index b613c2430f..a8522d3c03 100644 --- a/extension/lite/kanban/ext/model/lite.php +++ b/extension/lite/kanban/ext/model/lite.php @@ -133,8 +133,8 @@ public function getKanban4Group($executionID, $browseType, $groupBy, $searchValu $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('module', 'story', 'pri', 'severity')) and $object->$groupBy != $laneID) continue; + if(in_array($groupBy, array('assignedTo', 'type', 'category', 'source')) and $object->$groupBy != $laneID) continue; $cardData['id'] = $object->id; $cardData['order'] = $cardOrder; diff --git a/module/kanban/model.php b/module/kanban/model.php index 5035f028c4..9f91d93151 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1961,13 +1961,13 @@ class kanbanModel extends model $object = zget($objects, $cardID, array()); if(empty($object)) continue; - if(in_array($groupBy, array('module', 'story', 'pri', 'severity')) and (int)$object->$groupBy !== $laneID) continue; - if(in_array($groupBy, array('type', 'category', 'source')) and $object->$groupBy !== $laneID) continue; + if(in_array($groupBy, array('module', 'story', 'pri', 'severity')) and $object->$groupBy != $laneID) continue; + if(in_array($groupBy, array('type', 'category', 'source')) and $object->$groupBy != $laneID) continue; if($groupBy == 'assignedTo') { $laneID = (string)$laneID; if(empty($object->$groupBy)) $object->$groupBy = ''; - if(empty($object->teamMember) and (string)$object->$groupBy !== $laneID) continue; + if(empty($object->teamMember) and $object->$groupBy != $laneID) continue; if(!empty($object->teamMember) and !in_array($laneID, array_keys($object->teamMember), true)) continue; } From 17a417d9b2d84608e8fba10974f9916e21e8cece Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:01:38 +0800 Subject: [PATCH 088/235] + zin/searchform: add searchForm widget. --- lib/zin/func.php | 8 ++++++ lib/zin/wg/searchform/v1.php | 49 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 lib/zin/wg/searchform/v1.php diff --git a/lib/zin/func.php b/lib/zin/func.php index 87b3651211..b52fa4a61d 100644 --- a/lib/zin/func.php +++ b/lib/zin/func.php @@ -1074,6 +1074,14 @@ function searchToggle(): searchToggle return createWg('searchToggle', func_get_args()); } +/** + * Zentao search form widget. + */ +function searchForm(): searchForm +{ + return createWg('searchForm', func_get_args()); +} + /** * Zentao program menu widget. * diff --git a/lib/zin/wg/searchform/v1.php b/lib/zin/wg/searchform/v1.php new file mode 100644 index 0000000000..8deaaf5002 --- /dev/null +++ b/lib/zin/wg/searchform/v1.php @@ -0,0 +1,49 @@ + + * @package zin + * @link http://www.zentao.net + */ + +namespace zin; + +/** + * 搜索面板(searchForm)部件类 + * The searchForm widget class + */ +class searchForm extends wg +{ + /** + * Define widget properties. + * + * @var array + * @access protected + */ + protected static array $defineProps = array + ( + 'id?: string', // ID,可以与 searchToggle 配合使用。 + 'module: string', // 模块。 + 'container?: string', // 容器元素选择器,当被打开时在容器元素上显示类 show-search-form。 + 'show?: boolean', // 是否默认展示。 + 'simple?: boolean', // 是否为简单模式,不包含保存搜索条件和已保存的查询条件侧边栏。 + 'setting?: array', // 默认配置。 + 'url?: string', // 配置加载地址,默认为 search-buildForm-module。 + 'searchLoader?: string|array' // 搜索时 loadPage 参数。 + ); + + /** + * Build widget. + * + * @access protected + * @return wg + */ + protected function build(): wg + { + return zui::searchForm(inherit($this)); + } +} From 634de0c1294026b41f78f1392f58b82f1cfefc7a Mon Sep 17 00:00:00 2001 From: tanghucheng Date: Thu, 16 Nov 2023 20:08:34 -0500 Subject: [PATCH 089/235] * Fix block systemMode. --- module/block/lang/de.php | 2 +- module/block/lang/en.php | 2 +- module/block/lang/fr.php | 2 +- module/block/lang/zh-cn.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/block/lang/de.php b/module/block/lang/de.php index cbd47a8894..0cf0de76d5 100644 --- a/module/block/lang/de.php +++ b/module/block/lang/de.php @@ -486,7 +486,7 @@ $lang->block->zentaoclient->edition->linux64 = 'Linux'; $lang->block->zentaoclient->edition->mac64 = 'Mac OS'; $lang->block->guideTabs['flowchart'] = 'Flowchart'; -if($config->systemMode == 'ALM') $lang->block->guideTabs['systemMode'] = 'Operating Modes'; +if($config->systemMode != 'PLM') $lang->block->guideTabs['systemMode'] = 'Operating Modes'; $lang->block->guideTabs['visionSwitch'] = 'Interface Switch'; $lang->block->guideTabs['themeSwitch'] = 'Theme Switch'; $lang->block->guideTabs['preference'] = 'Personalized setting'; diff --git a/module/block/lang/en.php b/module/block/lang/en.php index e67c5f839a..307966a7ed 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -486,7 +486,7 @@ $lang->block->zentaoclient->edition->linux64 = 'Linux'; $lang->block->zentaoclient->edition->mac64 = 'Mac OS'; $lang->block->guideTabs['flowchart'] = 'Flowchart'; -if($config->systemMode == 'ALM') $lang->block->guideTabs['systemMode'] = 'Operating Modes'; +if($config->systemMode != 'PLM') $lang->block->guideTabs['systemMode'] = 'Operating Modes'; $lang->block->guideTabs['visionSwitch'] = 'Interface Switch'; $lang->block->guideTabs['themeSwitch'] = 'Theme Switch'; $lang->block->guideTabs['preference'] = 'Personalized setting'; diff --git a/module/block/lang/fr.php b/module/block/lang/fr.php index 4eacd18bc2..34a638b5b3 100644 --- a/module/block/lang/fr.php +++ b/module/block/lang/fr.php @@ -486,7 +486,7 @@ $lang->block->zentaoclient->edition->linux64 = 'Linux'; $lang->block->zentaoclient->edition->mac64 = 'Mac OS'; $lang->block->guideTabs['flowchart'] = 'Flowchart'; -if($config->systemMode == 'ALM') $lang->block->guideTabs['systemMode'] = 'Operating Modes'; +if($config->systemMode != 'PLM') $lang->block->guideTabs['systemMode'] = 'Operating Modes'; $lang->block->guideTabs['visionSwitch'] = 'Interface Switch'; $lang->block->guideTabs['themeSwitch'] = 'Theme Switch'; $lang->block->guideTabs['preference'] = 'Personalized setting'; diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index c275127102..f1ea0ddd4e 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -486,7 +486,7 @@ $lang->block->zentaoclient->edition->linux64 = 'Linux版'; $lang->block->zentaoclient->edition->mac64 = 'Mac版'; $lang->block->guideTabs['flowchart'] = '流程图'; -if($config->systemMode == 'ALM') $lang->block->guideTabs['systemMode'] = '运行模式'; +if($config->systemMode != 'PLM') $lang->block->guideTabs['systemMode'] = '运行模式'; $lang->block->guideTabs['visionSwitch'] = '界面切换'; $lang->block->guideTabs['themeSwitch'] = '主题切换'; $lang->block->guideTabs['preference'] = '个性化设置'; From 5a56f91b21c245920dd54a607f62789937a9fe17 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:11:19 +0800 Subject: [PATCH 090/235] * zin: refactor. --- www/js/zui3/zin.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/www/js/zui3/zin.js b/www/js/zui3/zin.js index 7a66ab3709..f22f3d31fa 100644 --- a/www/js/zui3/zin.js +++ b/www/js/zui3/zin.js @@ -687,11 +687,14 @@ url = lasShowModal.options.url; target = lasShowModal.id; } - options = $.extend(url ? {url: url} : {}, options); + options = $.extend(typeof url === 'object' ? (url || {}) : {url: url}, options); + target = target || options.target; + callback = callback || options.callback; + if(!target) return zui.Modal.open(options); else if(target === 'current') target = zui.Modal.query().id; - if(target[0] !== '#' && target[0] !== '.') target = `#${target}`; + if(typeof target === 'string' && target[0] !== '#' && target[0] !== '.') target = `#${target}`; const modal = zui.Modal.query(target); if(!modal) return; modal.render(options).then((result) => {if(result && callback) callback(modal.dialog);}); @@ -869,7 +872,7 @@ if(load === 'modal') { if(!options.target && event) options.target = $(event.target).closest('.modal').attr('id'); - return loadModal(options.url, options.target, options); + return loadModal(options); } if(load === 'target') return loadTarget(options); if(load !== 'APP' && typeof load === 'string') options.selector = load; From 4872b921cadb8c2c74a8f4bd8771faf37b3aaf33 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:11:38 +0800 Subject: [PATCH 091/235] * productplan: refactor. --- module/productplan/ui/browsebykanban.html.php | 6 +++--- module/productplan/ui/browsebylist.html.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/module/productplan/ui/browsebykanban.html.php b/module/productplan/ui/browsebykanban.html.php index c736bfb2c1..545c0620df 100644 --- a/module/productplan/ui/browsebykanban.html.php +++ b/module/productplan/ui/browsebykanban.html.php @@ -42,10 +42,10 @@ toolbar ), set::items($orderItems) ), - div + btnGroup ( - btn(setClass($viewType == 'list' ? 'text-primary' : 'text-darker'), set::icon('format-list-bulleted'), setData('type', 'list'), setClass('switchButton')), - btn(setClass($viewType == 'kanban' ? 'text-primary' : 'text-darker'), set::icon('kanban'), setData('type', 'kanban'), setClass('switchButton')) + btn(setClass($viewType == 'list' ? 'text-primary font-bold shadow-inner bg-canvas' : ''), set::icon('format-list-bulleted'), setData('type', 'list'), setClass('switchButton')), + btn(setClass($viewType == 'kanban' ? 'text-primary font-bold shadow-inner bg-canvas' : ''), set::icon('kanban'), setData('type', 'kanban'), setClass('switchButton')) ), common::hasPriv('productplan', 'create') ? item ( diff --git a/module/productplan/ui/browsebylist.html.php b/module/productplan/ui/browsebylist.html.php index 40c7857917..fa62e053fb 100644 --- a/module/productplan/ui/browsebylist.html.php +++ b/module/productplan/ui/browsebylist.html.php @@ -23,10 +23,10 @@ featureBar $canCreatePlan = common::canModify('product', $product) && common::hasPriv($app->rawModule, 'create'); toolbar ( - div + btnGroup ( - btn(setClass($viewType == 'list' ? 'text-primary' : 'text-darker'), set::icon('format-list-bulleted'), setData('type', 'list'), setClass('switchButton')), - btn(setClass($viewType == 'kanban' ? 'text-primary' : 'text-darker'), set::icon('kanban'), setData('type', 'kanban'), setClass('switchButton')) + btn(setClass($viewType == 'list' ? 'text-primary font-bold shadow-inner bg-canvas' : ''), set::icon('format-list-bulleted'), setData('type', 'list'), setClass('switchButton')), + btn(setClass($viewType == 'kanban' ? 'text-primary font-bold shadow-inner bg-canvas' : ''), set::icon('kanban'), setData('type', 'kanban'), setClass('switchButton')) ), $canCreatePlan ? item(set(array('icon' => 'plus', 'class' => 'primary', 'text' => $lang->productplan->create, 'url' => createLink($app->rawModule, 'create', "productID={$productID}&branch={$branch}")))) : null ); From 49071d5e89817d2810249b6d42f192ce27c92123 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:12:19 +0800 Subject: [PATCH 092/235] * bug: refactor. --- module/bug/js/edit.ui.js | 2 +- module/bug/ui/edit.html.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/module/bug/js/edit.ui.js b/module/bug/js/edit.ui.js index 62f8bde5b4..ba717fda97 100644 --- a/module/bug/js/edit.ui.js +++ b/module/bug/js/edit.ui.js @@ -31,7 +31,7 @@ function changeResolution(event) } } -function linkBug(event) +function linkBug() { const relatedBugs = $('[name^=relatedBug]').val(); var linkedBugs = ''; diff --git a/module/bug/ui/edit.html.php b/module/bug/ui/edit.html.php index 2abc768b0a..46fc984ae4 100644 --- a/module/bug/ui/edit.html.php +++ b/module/bug/ui/edit.html.php @@ -597,13 +597,13 @@ detailBody set::name('relatedBug[]'), set::items(isset($bug->relatedBugTitles) ? $bug->relatedBugTitles : array()) ), - common::hasPriv('bug', 'linkBugs') ? span + common::hasPriv('bug', 'linkBugs') ? inputGroupAddon ( - set('class', 'input-group-addon'), - a + setClass('p-0'), + btn ( - set('id', 'linkBug'), - set('href', 'javascript:;'), + setID('linkBug'), + setClass('ghost text-primary'), $lang->bug->linkBugs ) ) : null From 43664a170883459043f5276ad5431b6a35888300 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:12:34 +0800 Subject: [PATCH 093/235] * bug: refactor usage of searchForm. --- module/bug/control.php | 1 + module/bug/ui/linkbugs.html.php | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index e790da5746..a21444a55f 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -720,6 +720,7 @@ class bug extends control /* Assign. */ $this->view->title = $this->lang->bug->linkBugs . "BUG #$bug->id $bug->title {$this->lang->dash} " . $this->products[$bug->product]; + $this->view->bug = $bug; $this->view->bugs2Link = $this->bug->getBugs2Link($bugID, $bySearch, $excludeBugs, $queryID, $pager); $this->view->users = $this->user->getPairs('noletter'); $this->view->pager = $pager; diff --git a/module/bug/ui/linkbugs.html.php b/module/bug/ui/linkbugs.html.php index 984a53df6c..92ec9467eb 100644 --- a/module/bug/ui/linkbugs.html.php +++ b/module/bug/ui/linkbugs.html.php @@ -13,7 +13,25 @@ namespace zin; $cols = $config->bug->linkBugs->dtable->fieldList; $cols['product']['map'] = $products; -div(setID('searchFormPanel'), set('data-module', 'bug'), searchToggle(set::open(true), set::module('bug'))); +$footToolbar = array('items' => array()); +$footToolbar['items'][] = array('text' => $lang->save, 'btnType' => 'primary', 'className' => 'size-sm', 'data-on' => 'click', 'data-call' => 'fnLinkBugs', 'data-params' => 'event'); + +if(isInModal()) +{ + modalHeader + ( + set::title($lang->bug->linkBugs), + set::entityText($bug->title), + set::entityID($bug->id) + ); +} + +searchForm +( + set::module('bug'), + set::simple(true), + set::show(true) +); dtable ( @@ -21,7 +39,7 @@ dtable set::userMap($users), set::data($bugs2Link), set::footPager(usePager()), - set::footToolbar(array('items' => array(array('text' => $lang->save, 'btnType' => 'primary', 'className' => 'size-sm', 'data-on' => 'click', 'data-call' => 'fnLinkBugs', 'data-params' => 'event')))), + set::footToolbar($footToolbar), set::footer(array('checkbox', 'toolbar')) ); From 538fec68e57e8b7c3f44680ede97b5c1b3bc967d Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:14:32 +0800 Subject: [PATCH 094/235] * testcase: refactor with the searchForm wg. --- module/testcase/ui/linkbugs.html.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/module/testcase/ui/linkbugs.html.php b/module/testcase/ui/linkbugs.html.php index 01a693c91b..dc0121c0c3 100644 --- a/module/testcase/ui/linkbugs.html.php +++ b/module/testcase/ui/linkbugs.html.php @@ -10,6 +10,8 @@ declare(strict_types=1); */ namespace zin; +$footToolbar = array('items' => array(array('text' => $lang->save, 'btnType' => 'secondary', 'className' => 'link-btn'))); + modalHeader ( set::title($lang->testcase->linkBugs), @@ -17,19 +19,14 @@ modalHeader set::entityID($case->id) ); -div +searchForm ( - setID('searchFormPanel'), - set('data-module', 'bug'), - searchToggle - ( - set::open(true), - set::module('bug') - ) + set::className('surface'), + set::module('bug'), + set::simple(true), + set::show(true) ); -$footToolbar = array('items' => array(array('text' => $lang->save, 'btnType' => 'secondary', 'className' => 'link-btn'))); - dtable ( set::cols($config->testcase->linkbugs->dtable->fieldList), @@ -39,5 +36,3 @@ dtable set::footToolbar($footToolbar), set::footPager(usePager()) ); - -render('modalDialog'); From 1c24a0209b5e744c418d1366e0e45419cb3e5036 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 09:16:23 +0800 Subject: [PATCH 095/235] * Adjust page titie style. --- module/todo/ui/create.html.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/module/todo/ui/create.html.php b/module/todo/ui/create.html.php index 9613e7d773..d45a2885f4 100644 --- a/module/todo/ui/create.html.php +++ b/module/todo/ui/create.html.php @@ -40,12 +40,7 @@ for($day = 1; $day <= 31; $day ++) $days[$day] = $day . $lang->todo->day; formPanel ( - set::title(''), - div - ( - setClass('text-lg pb-2.5'), - $lang->todo->create - ), + set::title($lang->todo->create), formRow ( setClass('items-center'), From ebd103d677a10ba633b4b68bcb4f50e78e838230 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 09:17:07 +0800 Subject: [PATCH 096/235] * Adjust link jump mode. --- module/my/ui/todo.html.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/module/my/ui/todo.html.php b/module/my/ui/todo.html.php index f4d351ccbb..2b65706c4f 100644 --- a/module/my/ui/todo.html.php +++ b/module/my/ui/todo.html.php @@ -45,7 +45,6 @@ toolbar setClass('btn primary'), set::icon('plus'), set::url(helper::createLink('todo', 'create')), - set('data-toggle', 'modal'), $lang->todo->create ) : btn ( @@ -99,7 +98,6 @@ dtable set::emptyTip($lang->my->noTodo), set::createTip($lang->todo->create), set::createLink($canCreate ? createLink('todo', 'create') : ''), - set::createAttr("data-toggle='modal'"), set::footToolbar($footToolbar), set::footPager(usePager()), set::footer(array('checkbox', 'toolbar', hasPriv('todo', 'import2Today') && $importFuture ? jsRaw('window.generateHtml') : '', 'checkedInfo', 'flex', 'pager')) From 6b78d758bb70b01ffdedc901c5006d9b3ed9e982 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Fri, 17 Nov 2023 09:24:02 +0800 Subject: [PATCH 097/235] * Adjust task team style. --- module/task/ui/view.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/task/ui/view.html.php b/module/task/ui/view.html.php index bdfef66598..f1468df8b6 100644 --- a/module/task/ui/view.html.php +++ b/module/task/ui/view.html.php @@ -374,7 +374,7 @@ detailBody set::title($lang->task->team), h::table ( - setClass('table table-data'), + setClass('table condensed bordered'), setID('team'), h::thead ( From 1796d3ba1841a3f1bab0c89e4cf5761f793cadc5 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 09:32:39 +0800 Subject: [PATCH 098/235] - zin/dtable: remove unused css file. --- lib/zin/wg/dtable/css/v1.css | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 lib/zin/wg/dtable/css/v1.css diff --git a/lib/zin/wg/dtable/css/v1.css b/lib/zin/wg/dtable/css/v1.css deleted file mode 100644 index 5f1714c784..0000000000 --- a/lib/zin/wg/dtable/css/v1.css +++ /dev/null @@ -1,5 +0,0 @@ -.menu.menu-dtable-actions {display: flex; min-width: auto;} -.menu.menu-dtable-actions .icon {position: static!important; opacity: 1!important;} -.menu.menu-dtable-actions span.text {display: none;} -.menu.menu-dtable-actions > .menu-item > a {padding: 0;} -.menu.menu-dtable-actions > .menu-item > a:hover {background: none; color: var(--menu-hover-bg);} From d0df1ccf41a62759450def000760f02df0e09899 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 09:48:42 +0800 Subject: [PATCH 099/235] * Add tooltips for project statistic block. --- module/block/css/projectstatisticblock.ui.css | 2 + module/block/lang/zh-cn.php | 12 +- .../block/ui/projectstatisticblock.html.php | 313 ++++++++++-------- 3 files changed, 190 insertions(+), 137 deletions(-) diff --git a/module/block/css/projectstatisticblock.ui.css b/module/block/css/projectstatisticblock.ui.css index 235a431864..c78fb76934 100644 --- a/module/block/css/projectstatisticblock.ui.css +++ b/module/block/css/projectstatisticblock.ui.css @@ -10,6 +10,8 @@ .projectstatistic-block .project-statistic-table table td {padding-left: 0px; margin-top: 1rem;} .projectstatistic-block .tab-pane .nav-tabs>.nav-item>a:after {border-bottom: none;} .projectstatistic-block .scrum table th, .projectstatistic-block .scrum table td {width: 50%} +.projectstatistic-block .waterfall table th {width: 100px;} +.projectstatistic-block .table-data {overflow: hidden;} .projectstatistic-block .progress-circle text {font-size: 35px;} .projectstatistic-block .progress-circle .progress-text {position: relative;} .projectstatistic-block.block-long .progress-circle .progress-text {top: -57px;} diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index f1ea0ddd4e..ca74c0ce44 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -567,7 +567,7 @@ $lang->block->projectstatistic->bug = 'Bug'; $lang->block->projectstatistic->storyPoints = '总规模'; $lang->block->projectstatistic->done = '已完成'; $lang->block->projectstatistic->undone = '剩余'; -$lang->block->projectstatistic->costs = '总投入'; +$lang->block->projectstatistic->costs = '已投入'; $lang->block->projectstatistic->consumed = '消耗工时'; $lang->block->projectstatistic->remainder = '预计剩余'; $lang->block->projectstatistic->tasks = '总数量'; @@ -589,7 +589,9 @@ $lang->block->projectstatistic->lastestExecution = '最新执行'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon}已关闭"; $lang->block->projectstatistic->longTimeProject = "长期{$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = '总进度'; -$lang->block->projectstatistic->totalProgressTip = '总进度=已消耗工时/(已消耗工时+剩余工时)'; +$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数/(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)\n +按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。\n +按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。"; $lang->block->projectstatistic->currentCost = '当前成本'; $lang->block->projectstatistic->sv = '进度偏差率(SV)'; $lang->block->projectstatistic->pv = '计划完成(PV)'; @@ -708,3 +710,9 @@ $lang->block->tooltips = array(); $lang->block->tooltips['deliveryRate'] = '需求交付率=按产品统计的已交付研发需求数/(按产品统计的研发需求总数-按产品统计的无效研发需求数)*100%'; $lang->block->tooltips['effectiveStory'] = '按产品统计的研发需求总数:产品中研发需求的个数求和,过滤已删除的研发需求,过滤已删除的产品。'; $lang->block->tooltips['deliveredStory'] = '按产品统计的已交付研发需求数:产品中研发需求个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的研发需求,过滤已删除的产品。'; +$lang->block->tooltips['costs'] = '已投入=已消耗工时/每日可用工时'; +$lang->block->tooltips['sv'] = '进度偏差率=(EV-PV)/PV*100% '; +$lang->block->tooltips['ev'] = "实际完成=按项目统计的任务预计工时数*按项目统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除执行下的任务,过滤已删除的项目。\n 按项目统计的任务预计工时数:项目中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务,过滤已删除的项目。"; +$lang->block->tooltips['pv'] = '计划完成:瀑布项目中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的执行的任务,过滤已删除的项目。'; +$lang->block->tooltips['cv'] = '成本偏差率=(EV-AC)/AC*100%'; +$lang->block->tooltips['ac'] = '实际花费:瀑布项目中所有日志记录的工时之和,过滤已删除的项目。'; diff --git a/module/block/ui/projectstatisticblock.html.php b/module/block/ui/projectstatisticblock.html.php index 2442b5580b..6a67dc7f23 100644 --- a/module/block/ui/projectstatisticblock.html.php +++ b/module/block/ui/projectstatisticblock.html.php @@ -106,11 +106,34 @@ if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) $cellItems = array(); foreach($moduleItems as $item) { - $field = $item['field']; - $unit = $item['unit']; + $field = $item['field']; + $unit = $item['unit']; + $cellItems[] = item ( - set::name($lang->block->projectstatistic->{$field} . ': '), + set::name + ( + $lang->block->projectstatistic->{$field}, + !isset($lang->block->tooltips[$field]) ? ':' : null + ), + to::suffixName + ( + isset($lang->block->tooltips[$field]) ? icon + ( + 'help', + toggle::tooltip + ( + array + ( + 'title' => $lang->block->tooltips[$field], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ), + ':' + ) : null + ), span ( setClass('font-bold text-black mr-0.5'), @@ -153,35 +176,39 @@ else div ( setClass('flex justify-center w-full'), - zui::progressCircle + progressCircle ( - set('percent', $project->progress), - set('size', 112), - set('circleWidth', 6), - set('text', "{$project->progress}%"), - set('textY', 50), - set('textStyle', 'font-size: 30px;') - ) - ), - div - ( - setClass('flex justify-center w-full h-0'), - span - ( - setClass('text-gray text-md progress-text'), - $lang->block->projectstatistic->totalProgress, - icon + set::percent($project->progress), + set::size(112), + set::text(false), + set::circleWidth(0.06), + div(span(setClass('text-2xl font-bold'), $project->progress), '%'), + div ( - setClass('pl-0.5'), - toggle::tooltip(array('title' => $lang->block->projectstatistic->totalProgressTip)), - 'help' + setClass('row text-sm text-gray items-center gap-1'), + $lang->block->projectstatistic->totalProgress, + icon + ( + setClass('pl-0.5'), + toggle::tooltip + ( + array + ( + 'title' => $lang->block->projectstatistic->totalProgressTip, + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ), + 'help' + ) ) ) ) ); $cells[] = cell ( - setClass('project-statistic-table pl-4' . ($longBlock ? ' border-l' : ' mt-4')), + setClass('project-statistic-table waterfall pl-4' . ($longBlock ? ' border-l' : ' mt-4')), set::width($longBlock ? '32%' : '50%'), div ( @@ -192,86 +219,94 @@ else $lang->project->progress ) ), - h::table + tableData ( - setClass('table-data'), - h::tbody + item ( - h::tr + set::name($lang->block->projectstatistic->sv), + to::suffixName ( - h::th + icon ( - setClass('py-1.5 pr-2 font-normal nowrap items-center text-right'), - $lang->block->projectstatistic->sv, - icon + toggle::tooltip ( - toggle::tooltip(array('title' => '提示文本')), - 'help' + array + ( + 'title' => $lang->block->tooltips['sv'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) ), - ':' + 'help' ), - h::td - ( - setClass('py-1.5 pl-2'), - span - ( - setClass('font-bold text-black mr-1'), - (!empty($project->sv) ? $project->sv : 0) . $lang->percent - ) - ) + ':' ), - h::tr + span ( - h::th + setClass('font-bold text-black mr-1'), + (!empty($project->sv) ? $project->sv : 0) . $lang->percent + ) + ), + item + ( + set::name($lang->block->projectstatistic->pv), + to::suffixName + ( + icon ( - setClass('py-1.5 pr-2 font-normal nowrap items-center text-right'), - $lang->block->projectstatistic->pv, - icon + toggle::tooltip ( - toggle::tooltip(array('title' => '提示文本')), - 'help' + array + ( + 'title' => $lang->block->tooltips['pv'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) ), - ':' + 'help' ), - h::td - ( - setClass('py-1.5 pl-2'), - span - ( - setClass('font-bold text-black mr-1'), - (!empty($project->pv) ? $project->pv : 0) . $lang->percent - ) - ) + ':' ), - h::tr + span ( - h::th + setClass('font-bold text-black mr-1'), + (!empty($project->pv) ? $project->pv : 0) . $lang->percent + ) + ), + item + ( + set::name($lang->block->projectstatistic->ev), + to::suffixName + ( + icon ( - setClass('py-1.5 pr-2 font-normal nowrap items-center text-right'), - $lang->block->projectstatistic->ev, - icon + toggle::tooltip ( - toggle::tooltip(array('title' => '提示文本')), - 'help' + array + ( + 'title' => $lang->block->tooltips['ev'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) ), - ':' + 'help' ), - h::td - ( - setClass('py-1.5 pl-2'), - span - ( - setClass('font-bold text-black mr-1'), - (!empty($project->ev) ? $project->ev : 0) . $lang->percent - ) - ) + ':' + ), + span + ( + setClass('font-bold text-black mr-1'), + (!empty($project->ev) ? $project->ev : 0) . $lang->percent ) ) ) ); $cells[] = cell ( - setClass('project-statistic-table pl-4 border-l' . (!$longBlock ? ' mt-3' : '')), + setClass('project-statistic-table waterfall pl-4 border-l' . (!$longBlock ? ' mt-3' : '')), set::width($longBlock ? '32%' : '50%'), div ( @@ -282,79 +317,87 @@ else $lang->block->projectstatistic->currentCost ) ), - h::table + tableData ( - setClass('table-data'), - h::tbody + item ( - h::tr + set::name($lang->block->projectstatistic->cv), + to::suffixName ( - h::th + icon ( - setClass('py-1.5 pr-2 font-normal nowrap items-center text-right'), - $lang->block->projectstatistic->cv, - icon + toggle::tooltip ( - toggle::tooltip(array('title' => '提示文本')), - 'help' + array + ( + 'title' => $lang->block->tooltips['cv'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) ), - ':' + 'help' ), - h::td - ( - setClass('py-1.5 pl-2'), - span - ( - setClass('font-bold text-black mr-1'), - (!empty($project->cv) ? $project->cv : 0) . $lang->percent - ) - ) + ':' ), - h::tr + span ( - h::th - ( - setClass('py-1.5 pr-2 font-normal nowrap items-center text-right'), - $lang->block->projectstatistic->ev, - icon - ( - toggle::tooltip(array('title' => '提示文本')), - 'help' - ), - ':' - ), - h::td - ( - setClass('py-1.5 pl-2'), - span - ( - setClass('font-bold text-black mr-1'), - (!empty($project->ev) ? $project->ev : 0) . $lang->percent - ) - ) + setClass('font-bold text-black mr-1'), + (!empty($project->cv) ? $project->cv : 0) . $lang->percent ), - h::tr + ), + item + ( + set::name($lang->block->projectstatistic->ev), + to::suffixName ( - h::th + icon ( - setClass('py-1.5 pr-2 font-normal nowrap items-center text-right'), - $lang->block->projectstatistic->ac, - icon + toggle::tooltip ( - toggle::tooltip(array('title' => '提示文本')), - 'help' + array + ( + 'title' => $lang->block->tooltips['ev'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) ), - ':' + 'help' ), - h::td + ':' + ), + span + ( + setClass('font-bold text-black mr-1'), + (!empty($project->ev) ? $project->ev : 0) . $lang->percent + ) + ), + item + ( + set::name($lang->block->projectstatistic->ac), + to::suffixName + ( + icon ( - setClass('py-1.5 pl-2'), - span + toggle::tooltip ( - setClass('font-bold text-black mr-1'), - (!empty($project->ac) ? $project->ac : 0) . $lang->percent - ) - ) + array + ( + 'title' => $lang->block->tooltips['ac'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ), + 'help' + ), + ':' + ), + span + ( + setClass('font-bold text-black mr-1'), + (!empty($project->ac) ? $project->ac : 0) . $lang->percent ) ) ) From 3635666487348eeed9c26bec713b13656f8ae8f0 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 09:49:30 +0800 Subject: [PATCH 100/235] * Add suffixName block to table data item widget. --- lib/zin/wg/tabledata/v1.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/zin/wg/tabledata/v1.php b/lib/zin/wg/tabledata/v1.php index d90c0cb3cd..a173e15f64 100644 --- a/lib/zin/wg/tabledata/v1.php +++ b/lib/zin/wg/tabledata/v1.php @@ -28,7 +28,8 @@ class tableData extends wg h::th ( setClass('py-1.5 pr-2 font-normal nowrap text-right', $item->prop('thClass')), - $item->prop('name') + $item->prop('name'), + $item->block('suffixName') ), h::td ( From f8d5bd6c78e4bf3826ed28fd286990bb86959ea4 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 09:49:33 +0800 Subject: [PATCH 101/235] * Compatible parameter type. --- module/bug/control.php | 8 ++++---- module/bug/zen.php | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index a21444a55f..67c30f079a 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -105,7 +105,7 @@ class bug extends control /* Save the product id user last visited to session and cookie. */ $productID = $this->product->checkAccess($productID, $this->products); $product = $this->product->getByID($productID); - $branch = $this->bugZen->getBrowseBranch($branch, $product->type); + $branch = $this->bugZen->getBrowseBranch($branch, (string)$product->type); $browseType = $browseType ? strtolower($browseType) : 'unclosed'; /* 设置1.5级导航相关信息。*/ @@ -116,7 +116,7 @@ class bug extends control /* Set the order field. */ if(!$orderBy) $orderBy = $this->cookie->qaBugOrder ? $this->cookie->qaBugOrder : 'id_desc'; - $this->bugZen->setBrowseCookie($product, $branch, $browseType, $param, $orderBy); + $this->bugZen->setBrowseCookie((object)$product, $branch, $browseType, $param, $orderBy); $this->bugZen->setBrowseSession($browseType); @@ -127,9 +127,9 @@ class bug extends control $this->bugZen->buildBrowseSearchForm($productID, $branch, $queryID); $executions = $this->loadModel('execution')->getPairs($this->projectID, 'all', 'empty|withdelete|hideMultiple'); - $bugs = $this->bugZen->getBrowseBugs($product->id, $branch, $browseType, array_keys($executions), $moduleID, $queryID, $realOrderBy, $pager); + $bugs = $this->bugZen->getBrowseBugs((int)$product->id, $branch, $browseType, array_keys($executions), $moduleID, $queryID, $realOrderBy, $pager); - $this->bugZen->buildBrowseView($bugs, $product, $branch, $browseType, $moduleID, $executions, $param, $orderBy, $pager); + $this->bugZen->buildBrowseView($bugs, (object)$product, $branch, $browseType, $moduleID, $executions, $param, $orderBy, $pager); $this->display(); } diff --git a/module/bug/zen.php b/module/bug/zen.php index 27f9e16859..a775809c40 100644 --- a/module/bug/zen.php +++ b/module/bug/zen.php @@ -231,7 +231,8 @@ class bugZen extends bug */ private function getBranchOptions(int $productID): array { - $branches = $this->loadModel('branch')->getList($productID, 0, 'all'); + $branches = $this->loadModel('branch')->getList($productID, 0, 'all'); + $branchTagOption = array(); foreach($branches as $branchInfo) { $branchTagOption[$branchInfo->id] = $branchInfo->name . ($branchInfo->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : ''); @@ -1028,7 +1029,7 @@ class bugZen extends bug /* 获取分支列表。*/ /* Get branch options. */ $branchTagOption = array(); - if($product->type != 'normal') $branchTagOption = $this->getBranchOptions($product->id); + if($product->type != 'normal') $branchTagOption = $this->getBranchOptions((int)$product->id); /* 获取需求和任务的 id 列表。*/ /* Get story and task id list. */ @@ -1052,12 +1053,12 @@ class bugZen extends bug $this->view->orderBy = $orderBy; $this->view->pager = $pager; $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($product->id, 'bug', $showModule) : array(); - $this->view->modules = $this->tree->getOptionMenu($product->id, 'bug', 0, $branch); - $this->view->moduleTree = $this->tree->getTreeMenu($product->id, 'bug', 0, array('treeModel', 'createBugLink'), array(), $branch); + $this->view->modules = $this->tree->getOptionMenu((int)$product->id, 'bug', 0, $branch); + $this->view->moduleTree = $this->tree->getTreeMenu((int)$product->id, 'bug', 0, array('treeModel', 'createBugLink'), array(), $branch); $this->view->branchTagOption = $branchTagOption; $this->view->projectPairs = $this->loadModel('project')->getPairsByProgram(); $this->view->executions = $executions; - $this->view->plans = $this->loadModel('productplan')->getPairs($product->id); + $this->view->plans = $this->loadModel('productplan')->getPairs((int)$product->id); $this->view->tasks = $this->loadModel('task')->getPairsByIdList($taskIdList); $this->view->stories = $this->loadModel('story')->getPairsByList($storyIdList); $this->view->builds = $this->loadModel('build')->getBuildPairs(array($product->id), $branch); From e489e0ef6559e39a1407f2856820014a85d7b80d Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 17 Nov 2023 09:50:04 +0800 Subject: [PATCH 102/235] * Fix metric of todo list. --- .../user/scale/count_of_assigned_bug_in_user.php | 2 +- .../scale/count_of_assigned_case_in_user.php | 2 +- .../scale/count_of_assigned_task_in_user.php | 16 ++++++++++++++-- .../count_of_daily_finished_task_in_user.php | 8 ++++++-- .../scale/count_of_daily_fixed_bug_in_user.php | 2 +- module/metric/dataset.php | 1 + 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php b/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php index 185557a99a..9f846b028b 100755 --- a/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php @@ -9,7 +9,7 @@ * 度量名称:按人员统计的待处理Bug数 * 单位:个 * 描述:按人员统计的待处理Bug数表示每个人待处理的Bug数量之和。反映了每个人需要处理的Bug数量上的规模。该数值越大,说明需要投入越多的时间解决Bug。 - * 定义:所有Bug个数求和;指派给为某人;过滤已删除的Bug;过滤已删除产品的Bug; + * 定义:所有Bug个数求和;指派给为某人;过滤状态为已关闭的Bug;过滤已删除的Bug;过滤已删除产品的Bug; * * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) * @author zhouxin diff --git a/module/metric/calc/user/scale/count_of_assigned_case_in_user.php b/module/metric/calc/user/scale/count_of_assigned_case_in_user.php index 576927dfa8..d9a2943407 100755 --- a/module/metric/calc/user/scale/count_of_assigned_case_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_case_in_user.php @@ -9,7 +9,7 @@ * 度量名称:按人员统计的待处理用例数 * 单位:个 * 描述:按人员统计的待处理用例数表示每个人待处理的用例数量之和。反映了每个人需要处理的用例数量上的规模。该数值越大,说明需要投入越多的时间处理用例。 - * 定义:所有用例个数求和;指派给为某人;过滤已删除的用例;过滤已删除产品的用例; + * 定义:所有用例个数求和;指派给为某人;测试单的状态不为已完成;过滤已删除的用例;过滤已删除测试单的用例;过滤已删除产品的用例; * * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) * @author zhouxin diff --git a/module/metric/calc/user/scale/count_of_assigned_task_in_user.php b/module/metric/calc/user/scale/count_of_assigned_task_in_user.php index dcbdb94226..5f2ebd78a9 100755 --- a/module/metric/calc/user/scale/count_of_assigned_task_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_task_in_user.php @@ -9,7 +9,7 @@ * 度量名称:按人员统计的待处理任务数 * 单位:个 * 描述:按人员统计的待处理任务数表示每个人待处理的任务数量之和。反映了每个人在需要处理的任务数量上的规模。该数值越大,说明需要投入越多的时间处理任务。 - * 定义:所有任务个数求和;指派给为某人;过滤已删除的任务;过滤已删除项目的任务;过滤已删除执行的任务; + * 定义:任务个数求和;指派给为某人,并且过滤任务状态为已关闭和已取消的任务;如果任务为多人任务,并且过滤状态为已完成的任务;过滤已删除的任务;过滤已删除项目的任务;过滤已删除执行的任务;过滤挂起的执行和项目; * * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) * @author qixinzhi @@ -22,7 +22,7 @@ class count_of_assigned_task_in_user extends baseCalc { public $dataset = 'getTasks'; - public $fieldList = array('t1.assignedTo', 't1.status'); + public $fieldList = array('t1.assignedTo', 't1.status', 't1.mode', 't5.account', 't3.status as projectStatus', 't2.status as executionStatus'); public $result = array(); @@ -30,9 +30,21 @@ class count_of_assigned_task_in_user extends baseCalc { $assignedTo = $row->assignedTo; $status = $row->status; + $mode = $row->mode; + + $projectStatus = $row->projectStatus; + $executionStatus = $row->executionStatus; if(empty($assignedTo) || $assignedTo == 'closed') return false; if($status == 'closed' || $status == 'cancel') return false; + if($projectStatus == 'suspended' || $executionStatus == 'suspended') return false; + + if($mode == 'multi') + { + if($status == 'done') return false; + $assignedTo = $row->account; + } + if(!isset($this->result[$assignedTo])) $this->result[$assignedTo] = 0; $this->result[$assignedTo] += 1; diff --git a/module/metric/calc/user/scale/count_of_daily_finished_task_in_user.php b/module/metric/calc/user/scale/count_of_daily_finished_task_in_user.php index a7e0a58e55..0f7393a9e9 100755 --- a/module/metric/calc/user/scale/count_of_daily_finished_task_in_user.php +++ b/module/metric/calc/user/scale/count_of_daily_finished_task_in_user.php @@ -9,7 +9,7 @@ * 度量名称:按人员统计的每日完成任务数 * 单位:个 * 描述:按人员统计的日完成任务数表示每个人每日完成的任务数量之和。反映了每个人每日完成的任务规模。该数值越大,可能说明工作效率越高,任务完成速度越快。 - * 定义:某人某日完成的任务个数求和; + * 定义:任务个数求和;由谁完成为某人;过滤已删除的任务;过滤已删除项目的任务;过滤已删除执行的任务;过滤挂起的执行和项目; * * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) * @author qixinzhi @@ -22,7 +22,7 @@ class count_of_daily_finished_task_in_user extends baseCalc { public $dataset = 'getTasks'; - public $fieldList = array('t1.finishedDate', 't1.finishedBy'); + public $fieldList = array('t1.finishedDate', 't1.finishedBy', 't3.status as projectStatus', 't2.status as executionStatus'); public $result = array(); @@ -31,7 +31,11 @@ class count_of_daily_finished_task_in_user extends baseCalc $finishedDate = $row->finishedDate; $finishedBy = $row->finishedBy; + $projectStatus = $row->projectStatus; + $executionStatus = $row->executionStatus; + if(empty($finishedDate) || empty($finishedBy)) return false; + if($projectStatus == 'suspended' || $executionStatus == 'suspended') return false; $year = substr($finishedDate, 0, 4); if($year == '0000') return false; diff --git a/module/metric/calc/user/scale/count_of_daily_fixed_bug_in_user.php b/module/metric/calc/user/scale/count_of_daily_fixed_bug_in_user.php index cb569f9c2c..962a5bdd17 100755 --- a/module/metric/calc/user/scale/count_of_daily_fixed_bug_in_user.php +++ b/module/metric/calc/user/scale/count_of_daily_fixed_bug_in_user.php @@ -9,7 +9,7 @@ * 度量名称:按人员统计的日解决Bug数 * 单位:个 * 描述:按人员统计的日解决Bug数表示每个人每日解决的Bug数量之和。反映了每个人每日解决Bug的规模。该数值越大,可能说明Bug的解决能力越强,工作效率越高。 - * 定义:所有Bug个数求和;解决者为某人; + * 定义:所有Bug个数求和;bug状态为已解决和已关闭;解决者为某人;过滤已删除的bug;过滤已删除产品的bug; * * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) * @author zhouxin diff --git a/module/metric/dataset.php b/module/metric/dataset.php index a0cf4482fa..13d9d1cf66 100644 --- a/module/metric/dataset.php +++ b/module/metric/dataset.php @@ -409,6 +409,7 @@ class dataset return $this->dao->select($fieldList)->from(TABLE_TASK)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id') ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') + ->leftJoin(TABLE_TASKTEAM)->alias('t4')->on('t1.id=t4.task') ->where('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t3.deleted')->eq(0) From ea54d4f2650940c5d23bd343951fcf834c12518d Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 09:51:54 +0800 Subject: [PATCH 103/235] * Modify style of project statistic block. --- module/block/css/projectstatisticblock.ui.css | 1 + 1 file changed, 1 insertion(+) diff --git a/module/block/css/projectstatisticblock.ui.css b/module/block/css/projectstatisticblock.ui.css index c78fb76934..9501ce1d28 100644 --- a/module/block/css/projectstatisticblock.ui.css +++ b/module/block/css/projectstatisticblock.ui.css @@ -12,6 +12,7 @@ .projectstatistic-block .scrum table th, .projectstatistic-block .scrum table td {width: 50%} .projectstatistic-block .waterfall table th {width: 100px;} .projectstatistic-block .table-data {overflow: hidden;} +.projectstatistic-block .table-data td {white-space: nowrap;} .projectstatistic-block .progress-circle text {font-size: 35px;} .projectstatistic-block .progress-circle .progress-text {position: relative;} .projectstatistic-block.block-long .progress-circle .progress-text {top: -57px;} From bb8319a198b730bb301f6c497007d67f6e7399ae Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 08:38:34 +0800 Subject: [PATCH 104/235] * Change to new writing method. --- module/bug/ui/view.html.php | 42 +++++++++++++++++---------- module/task/ui/activate.html.php | 30 +++++++++++-------- module/zanode/ui/create.html.php | 22 +++++++++----- module/zanode/ui/createimage.html.php | 2 +- module/zanode/ui/view.html.php | 14 ++++----- 5 files changed, 67 insertions(+), 43 deletions(-) diff --git a/module/bug/ui/view.html.php b/module/bug/ui/view.html.php index b402a8cee4..1045b1ec5a 100644 --- a/module/bug/ui/view.html.php +++ b/module/bug/ui/view.html.php @@ -85,8 +85,14 @@ if(!empty($legendBasic['mailto']['text'])) $duplicateLink = $bug->duplicateBug && $canViewBug ? a ( set('href', $this->createLink('bug', 'view', "bugID={$bug->duplicateBug}")), - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setData + ( + array + ( + 'toggle' => 'modal', + 'size' => 'lg', + ) + ), $bug->duplicateBugTitle ) : ''; $duplicateBug = $bug->duplicateBug ? span("#{$bug->duplicateBug}:", $duplicateLink) : ''; @@ -97,9 +103,15 @@ foreach($legendMisc['relatedBug']['text'] as $relatedBugID => $relatedBugTitle) $relatedBugs[] = div(a ( set('href', $this->createLink('bug', 'view', "bugID={$relatedBugID}")), - set('data-toggle', 'modal'), - set('data-size', 'lg'), - span(label(set::className('dark-outline rounded-full mr-2'), $relatedBugID), $relatedBugTitle) + setData + ( + array + ( + 'toggle' => 'modal', + 'size' => 'lg', + ) + ), + span(label(setClass('dark-outline rounded-full mr-2'), $relatedBugID), $relatedBugTitle) )); } @@ -109,8 +121,8 @@ foreach($legendMisc['linkMR']['text'] as $MRID => $linkMRTitle) $linkMR[] = div(a ( $canViewMR ? set('href', $this->createLink('mr', 'view', "MRID={$MRID}")) : null, - set('data-app', 'devops'), - span(label(set::className('dark-outline rounded-full mr-2'), $MRID), $linkMRTitle) + setData(array('data-app' => 'devops')), + span(label(setClass('dark-outline rounded-full mr-2'), $MRID), $linkMRTitle) )); } @@ -119,7 +131,7 @@ foreach($legendMisc['linkCommit']['text'] as $commit) { $linkCommits[] = div(a ( - set('data-app', 'devops'), + setData(array('app' => 'devops')), $canViewRepo ? set('href', $this->createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}")) : null, "{$commit->comment}" )); @@ -151,7 +163,7 @@ $legendMain['story']['text'] = $bug->story ? div ')' ) : '' ) : ''; -$legendMain['task']['text'] = $bug->task ? div(label(set('class', 'dark-outline rounded-full size-sm mr-2'), $bug->task), span($bug->taskName)) : '';; +$legendMain['task']['text'] = $bug->task ? div(label(setClass('dark-outline rounded-full size-sm mr-2'), $bug->task), span($bug->taskName)) : '';; $legendMisc['relatedBug']['text'] = $relatedBugs; $legendMisc['linkCommit']['text'] = $linkCommits; $legendMisc['linkMR']['text'] = $linkMR; @@ -237,7 +249,7 @@ detailBody floatToolbar ( set::object($bug), - isAjaxRequest('modal') ? null : to::prefix(backBtn(set::icon('back'), set::className('ghost text-white'), $lang->goback)), + isAjaxRequest('modal') ? null : to::prefix(backBtn(set::icon('back'), setClass('ghost text-white'), $lang->goback)), set::main($actions['mainActions']), set::suffix($actions['suffixActions']) ), @@ -295,15 +307,15 @@ detailBody modal ( - set::id('toTask'), + setID('toTask'), set::modalProps(array('title' => $lang->bug->selectProjects)), to::footer ( div ( - set::className('toolbar gap-4 w-full justify-center'), - btn($lang->bug->nextStep, set::id('toTaskButton'), setClass('primary')), - btn($lang->cancel, set::id('cancelButton'), set('data-dismiss', 'modal')) + setClass('toolbar gap-4 w-full justify-center'), + btn($lang->bug->nextStep, setID('toTaskButton'), setClass('primary')), + btn($lang->cancel, setID('cancelButton'), setData(array('dismiss' => 'modal'))) ) ), formPanel @@ -329,7 +341,7 @@ modal set::required(true), inputGroup ( - set('id', 'executionBox'), + setID('executionBox'), picker ( set::name('execution'), diff --git a/module/task/ui/activate.html.php b/module/task/ui/activate.html.php index 1762f180c7..4e2f5da569 100644 --- a/module/task/ui/activate.html.php +++ b/module/task/ui/activate.html.php @@ -60,11 +60,11 @@ if($isMultiple) set::label($lang->task->mode), inputGroup ( - set::className('no-background'), + setClass('no-background'), zget($lang->task->modeList, $task->mode), input ( - set::className('hidden'), + setClass('hidden'), set::name('mode'), set::value($task->mode) ) @@ -80,7 +80,7 @@ if($isMultiple) setClass('items-center'), checkbox ( - set::id('multiple'), + setID('multiple'), set::name('multiple'), set::text($lang->task->manageTeam), set::rootClass('ml-4'), @@ -109,9 +109,9 @@ if($isMultiple) { $modalTeamBtn = btn( set::text($lang->task->team), - set::className('team-group hidden'), + setClass('team-group hidden'), set::url('#modalTeam'), - set('data-toggle', 'modal') + setData(array('toggle' => 'modal')) ); } @@ -129,9 +129,15 @@ foreach($task->team as $member) $teamForm[] = h::tr ( setClass("member member-{$member->status}"), - set('data-estimate', (float)$member->estimate), - set('data-consumed', (float)$member->consumed), - set('data-left', (float)$member->left), + set + ( + array + ( + 'estimate' => (float)$member->estimate, + 'consumed' => (float)$member->consumed, + 'left' => (float)$member->left + ) + ), h::td ( setClass('team-index'), @@ -354,25 +360,25 @@ formPanel ( modal ( - set::id('modalTeam'), + setID('modalTeam'), + setData(array('backdrop' => false)), set::title($lang->task->team), set::footerClass('flex-center'), - set('data-backdrop', false), to::footer ( div(setClass('multi-append')), btn ( + setID('confirmButton'), setClass('primary btn-wide'), - set::id('confirmButton'), set::text($lang->confirm), on::click('checkTeam') ) ), h::table ( + setID('teamTable'), setClass('table table-form'), - set::id('teamTable'), $teamForm ) ) diff --git a/module/zanode/ui/create.html.php b/module/zanode/ui/create.html.php index b12dd5ab78..26c406890c 100644 --- a/module/zanode/ui/create.html.php +++ b/module/zanode/ui/create.html.php @@ -22,11 +22,17 @@ formPanel icon ( 'help', - set('data-toggle', 'tooltip'), - set('data-placement', 'right'), - set('data-title', $lang->zanode->tips), - set('data-type', 'white'), - set('data-class-name', 'text-gray border border-light'), + setData + ( + array + ( + 'toggle' => 'tooltip', + 'placement' => 'right', + 'title' => $lang->zanode->tips, + 'type' => 'white', + 'class-name' => 'text-gray border border-light' + ) + ), setClass('text-gray') ) )), @@ -59,7 +65,7 @@ formPanel ( set::href(createLink('zahost', 'create')), $lang->zahost->create, - set('data-toggle', 'modal'), + setData(array('data-toggle' => 'modal')), setClass('leading-8 ml-2') ) ), @@ -147,11 +153,11 @@ formPanel ), formRow ( - set::id('osNamePhysicsContainer'), + setID('osNamePhysicsContainer'), setClass('hidden'), formGroup ( - set::id('osNamePhysicsPre'), + setID('osNamePhysicsPre'), set::label($lang->zanode->osName), set::items($config->zanode->osType), set::value('linux'), diff --git a/module/zanode/ui/createimage.html.php b/module/zanode/ui/createimage.html.php index 36e9b83f06..c7c5a8e518 100644 --- a/module/zanode/ui/createimage.html.php +++ b/module/zanode/ui/createimage.html.php @@ -24,7 +24,7 @@ if($task) modalHeader(set::title($lang->zanode->createImage)); !$task ? formPanel ( in_array($node->status, array('shutdown', 'shutoff')) ? null : set::ajax(array('beforeSubmit' => jsRaw("() => zui.Modal.confirm('{$lang->zanode->createImageNotice}')"))), - set::id('createImageForm'), + setID('createImageForm'), set::title($lang->zanode->createImage), formGroup ( diff --git a/module/zanode/ui/view.html.php b/module/zanode/ui/view.html.php index 4db6143b10..262d229b1a 100644 --- a/module/zanode/ui/view.html.php +++ b/module/zanode/ui/view.html.php @@ -87,7 +87,7 @@ if($zanode->hostType == 'physics') h::textarea ( setClass('hidden'), - set::id('ssh-copy'), + setID('ssh-copy'), $ssh ) ) @@ -191,7 +191,7 @@ else h::textarea ( setClass('hidden'), - set::id('ssh-copy'), + setID('ssh-copy'), $ssh ) ) @@ -279,7 +279,7 @@ else setClass('ml-2'), span ( - set::id('pwd-text'), + setID('pwd-text'), str_repeat('*', strlen($config->zanode->defaultPwd)) ), h::button @@ -306,7 +306,7 @@ else ), h::textarea ( - set::id('pwd-copy'), + setID('pwd-copy'), setClass('hidden'), $config->zanode->defaultPwd ) @@ -409,7 +409,7 @@ detailBody ), div ( - set::id('statusContainer') + setID('statusContainer') ), div ( @@ -425,7 +425,7 @@ detailBody html($lang->zanode->init->initFailNoticeOnPhysics), textarea ( - set::id('initBash'), + setID('initBash'), setClass('hidden'), $initBash ), @@ -464,7 +464,7 @@ detailBody $lang->zanode->createSnapshot, set::url(createLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}")), set::icon('plus'), - set('data-toggle', 'modal'), + setData(array('toggle' => 'modal')), set::disabled($zanode->status != 'running' ? true : false) ) ) From d7526fe0e9a9ab1b802fd3a702e4aadfcad2f90a Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 09:53:32 +0800 Subject: [PATCH 105/235] * Change to new writing method. --- module/bug/ui/report.html.php | 38 +++++++++++++++++++++++------------ module/bug/ui/view.html.php | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/module/bug/ui/report.html.php b/module/bug/ui/report.html.php index 22d4f5a818..72e321ae13 100644 --- a/module/bug/ui/report.html.php +++ b/module/bug/ui/report.html.php @@ -49,22 +49,22 @@ foreach($lang->report->typeList as $type => $typeName) set::param($type), set::key($type), to::prefix(icon($type == 'default' ? 'list-alt' : "chart-{$type}")), - div(set::className('pb-4 pt-2'), span(set::className('text-gray'), html(str_replace('%tab%', $lang->bug->unclosed . $lang->bug->common, $lang->report->notice->help)))), + div(setClass('pb-4 pt-2'), span(setClass('text-gray'), html(str_replace('%tab%', $lang->bug->unclosed . $lang->bug->common, $lang->report->notice->help)))), div($echarts) ); } div ( - set::className('flex items-start'), + setClass('flex items-start'), cell ( set::width('240'), - set::className('bg-white p-4 mr-5'), - div(set::className('pb-2'), span(set::className('font-bold'), $lang->bug->report->select)), + setClass('bg-white p-4 mr-5'), + div(setClass('pb-2'), span(setClass('font-bold'), $lang->bug->report->select)), div ( - set::className('pb-2'), + setClass('pb-2'), control ( set::type('checkList'), @@ -74,24 +74,36 @@ div ), btn ( - set('data-on', 'click'), - set('data-call', 'selectAll'), + setData + ( + array + ( + 'on' => 'click', + 'call' => 'selectAll', + ) + ), $lang->selectAll ), btn ( - set::className('primary ml-4 inited'), - set('data-on', 'click'), - set('data-call', 'clickInit'), - set('data-params', 'event'), + setClass('primary ml-4 inited'), + setData + ( + array + ( + 'on' => 'click', + 'call' => 'clickInit', + 'params' => 'event', + ) + ), $lang->bug->report->create ) ), cell ( set::flex('1'), - set::className('bg-white px-4 py-2'), - set::id('report'), + setClass('bg-white px-4 py-2'), + setID('report'), tabs($tabItems) ) ); diff --git a/module/bug/ui/view.html.php b/module/bug/ui/view.html.php index 1045b1ec5a..135e9da9c7 100644 --- a/module/bug/ui/view.html.php +++ b/module/bug/ui/view.html.php @@ -121,7 +121,7 @@ foreach($legendMisc['linkMR']['text'] as $MRID => $linkMRTitle) $linkMR[] = div(a ( $canViewMR ? set('href', $this->createLink('mr', 'view', "MRID={$MRID}")) : null, - setData(array('data-app' => 'devops')), + setData(array('app' => 'devops')), span(label(setClass('dark-outline rounded-full mr-2'), $MRID), $linkMRTitle) )); } From 6317130e2dcfa99ecb27490da3d2db204e9d86c6 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 09:57:16 +0800 Subject: [PATCH 106/235] * Add tooltip to execution statistic block. --- module/block/lang/zh-cn.php | 19 ++++++++++--------- .../block/ui/executionstatisticblock.html.php | 11 ++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index ca74c0ce44..e7feed70f8 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -707,12 +707,13 @@ $lang->block->moduleList['dynamic'] = $lang->block->dynamic; $lang->block->moduleList['html'] = $lang->block->html; $lang->block->tooltips = array(); -$lang->block->tooltips['deliveryRate'] = '需求交付率=按产品统计的已交付研发需求数/(按产品统计的研发需求总数-按产品统计的无效研发需求数)*100%'; -$lang->block->tooltips['effectiveStory'] = '按产品统计的研发需求总数:产品中研发需求的个数求和,过滤已删除的研发需求,过滤已删除的产品。'; -$lang->block->tooltips['deliveredStory'] = '按产品统计的已交付研发需求数:产品中研发需求个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的研发需求,过滤已删除的产品。'; -$lang->block->tooltips['costs'] = '已投入=已消耗工时/每日可用工时'; -$lang->block->tooltips['sv'] = '进度偏差率=(EV-PV)/PV*100% '; -$lang->block->tooltips['ev'] = "实际完成=按项目统计的任务预计工时数*按项目统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除执行下的任务,过滤已删除的项目。\n 按项目统计的任务预计工时数:项目中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务,过滤已删除的项目。"; -$lang->block->tooltips['pv'] = '计划完成:瀑布项目中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的执行的任务,过滤已删除的项目。'; -$lang->block->tooltips['cv'] = '成本偏差率=(EV-AC)/AC*100%'; -$lang->block->tooltips['ac'] = '实际花费:瀑布项目中所有日志记录的工时之和,过滤已删除的项目。'; +$lang->block->tooltips['deliveryRate'] = '需求交付率=按产品统计的已交付研发需求数/(按产品统计的研发需求总数-按产品统计的无效研发需求数)*100%'; +$lang->block->tooltips['effectiveStory'] = '按产品统计的研发需求总数:产品中研发需求的个数求和,过滤已删除的研发需求,过滤已删除的产品。'; +$lang->block->tooltips['deliveredStory'] = '按产品统计的已交付研发需求数:产品中研发需求个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的研发需求,过滤已删除的产品。'; +$lang->block->tooltips['costs'] = '已投入=已消耗工时/每日可用工时'; +$lang->block->tooltips['sv'] = '进度偏差率=(EV-PV)/PV*100% '; +$lang->block->tooltips['ev'] = "实际完成=按项目统计的任务预计工时数*按项目统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除执行下的任务,过滤已删除的项目。\n 按项目统计的任务预计工时数:项目中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务,过滤已删除的项目。"; +$lang->block->tooltips['pv'] = '计划完成:瀑布项目中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的执行的任务,过滤已删除的项目。'; +$lang->block->tooltips['cv'] = '成本偏差率=(EV-AC)/AC*100%'; +$lang->block->tooltips['ac'] = '实际花费:瀑布项目中所有日志记录的工时之和,过滤已删除的项目。'; +$lang->block->tooltips['executionProgress'] = "执行进度=按执行统计的任务消耗工时数/(按执行统计的任务消耗工时数+按执行统计的任务剩余工时数)\n 按执行统计的任务消耗工时数:执行中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。\n 按执行统计的任务剩余工时数:执行中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。"; diff --git a/module/block/ui/executionstatisticblock.html.php b/module/block/ui/executionstatisticblock.html.php index e4d9e8d265..f8fc5adadf 100644 --- a/module/block/ui/executionstatisticblock.html.php +++ b/module/block/ui/executionstatisticblock.html.php @@ -138,7 +138,16 @@ statisticBlock icon ( 'help', - toggle::tooltip(array('title' => '提示文本')), + toggle::tooltip + ( + array + ( + 'title' => $lang->block->tooltips['executionProgress'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ), setClass('text-light ml-0.5') ) ) From 0c99598a53e9228e0a46f6505a161512595de064 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 09:58:05 +0800 Subject: [PATCH 107/235] * Change to new writing method. --- module/zanode/ui/create.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/zanode/ui/create.html.php b/module/zanode/ui/create.html.php index 26c406890c..6a19ee0f0d 100644 --- a/module/zanode/ui/create.html.php +++ b/module/zanode/ui/create.html.php @@ -65,7 +65,7 @@ formPanel ( set::href(createLink('zahost', 'create')), $lang->zahost->create, - setData(array('data-toggle' => 'modal')), + setData(array('toggle' => 'modal')), setClass('leading-8 ml-2') ) ), From 0d41f941508371e4829b68b18b513b3813c5ba50 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Fri, 17 Nov 2023 10:07:49 +0800 Subject: [PATCH 108/235] * Delete unused code. --- lib/zin/wg/dtable/v1.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/zin/wg/dtable/v1.php b/lib/zin/wg/dtable/v1.php index 3895adebcd..48e2f9ce99 100644 --- a/lib/zin/wg/dtable/v1.php +++ b/lib/zin/wg/dtable/v1.php @@ -21,11 +21,6 @@ class dtable extends wg static $dtableID = 0; - public static function getPageCSS(): string|false - { - return file_get_contents(__DIR__ . DS . 'css' . DS . 'v1.css'); - } - protected function created() { global $app; From 54349bb0ad218193ca3bc6fc532066e27f8b8cd4 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 17 Nov 2023 10:12:29 +0800 Subject: [PATCH 109/235] * Fix metric field list with 'as'. --- module/metric/model.php | 2 +- module/metric/zen.php | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/module/metric/model.php b/module/metric/model.php index 4b72415e0b..82e05f88b6 100755 --- a/module/metric/model.php +++ b/module/metric/model.php @@ -488,7 +488,7 @@ class metricModel extends model $aliasList = array(); foreach($uniqueList as $field) { - if(strpos($field, '.') === false) + if(strpos($field, '.') === false || strpos(strtoupper($field), ' AS ') !== false) { $aliasList[] = $field; continue; diff --git a/module/metric/zen.php b/module/metric/zen.php index 68465b748a..084e8d3dc2 100644 --- a/module/metric/zen.php +++ b/module/metric/zen.php @@ -245,9 +245,18 @@ class metricZen extends metric $pureRow = new stdclass(); foreach($calc->fieldList as $field) { - $extractField = explode('.', $field); - $pureField = end($extractField); - $aliasField = str_replace('.', '_', $field); + if(strpos(strtoupper($field), ' AS ') !== false) + { + $extractField = explode(' AS ', $field); + $pureField = end($extractField); + $aliasField = $pureField; + } + else + { + $extractField = explode('.', $field); + $pureField = end($extractField); + $aliasField = str_replace('.', '_', $field); + } $pureRow->$pureField = $row->$aliasField; } From 85eb514c2a8c6131ef5884045399b9a3e277b7fa Mon Sep 17 00:00:00 2001 From: daitingting Date: Fri, 17 Nov 2023 02:13:12 +0000 Subject: [PATCH 110/235] * Unset link. --- module/program/ui/stakeholder.html.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/program/ui/stakeholder.html.php b/module/program/ui/stakeholder.html.php index 299d31282d..272c321af2 100644 --- a/module/program/ui/stakeholder.html.php +++ b/module/program/ui/stakeholder.html.php @@ -56,6 +56,7 @@ $fieldListExtend['id']['type'] = 'checkID'; $this->config->stakeholder->dtable->fieldList = $fieldListExtend; $cols = $this->loadModel('datatable')->getSetting('stakeholder'); +unset($cols['name']['link']); /* Set list and menu of actions to customize the actions of stakeholder in program module. */ $cols['actions']['list'] = array('unlinkStakeholder' => array From 22fbd1752ea08ece231c3456bdb3d002261c7031 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Fri, 17 Nov 2023 10:17:46 +0800 Subject: [PATCH 111/235] * Remove useless code. --- module/task/ui/view.html.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/task/ui/view.html.php b/module/task/ui/view.html.php index f1468df8b6..37d70f030d 100644 --- a/module/task/ui/view.html.php +++ b/module/task/ui/view.html.php @@ -22,7 +22,6 @@ detailHeader ) : null, entityLabel ( - set::text(''), set ( array From ad6e2382bca5c1cf23a7564cf3b10bfcf547d91f Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 17 Nov 2023 10:18:23 +0800 Subject: [PATCH 112/235] * Fix table alias of account. --- .../metric/calc/user/scale/count_of_assigned_task_in_user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/metric/calc/user/scale/count_of_assigned_task_in_user.php b/module/metric/calc/user/scale/count_of_assigned_task_in_user.php index 5f2ebd78a9..98514b520b 100755 --- a/module/metric/calc/user/scale/count_of_assigned_task_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_task_in_user.php @@ -22,7 +22,7 @@ class count_of_assigned_task_in_user extends baseCalc { public $dataset = 'getTasks'; - public $fieldList = array('t1.assignedTo', 't1.status', 't1.mode', 't5.account', 't3.status as projectStatus', 't2.status as executionStatus'); + public $fieldList = array('t1.assignedTo', 't1.status', 't1.mode', 't4.account', 't3.status as projectStatus', 't2.status as executionStatus'); public $result = array(); From dafb30eb92584d9c18203fb2db4c80810c6e46c4 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Fri, 17 Nov 2023 10:25:04 +0800 Subject: [PATCH 113/235] * Add user map for task children dtable. --- module/task/ui/view.html.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/task/ui/view.html.php b/module/task/ui/view.html.php index 37d70f030d..7ab6385865 100644 --- a/module/task/ui/view.html.php +++ b/module/task/ui/view.html.php @@ -223,6 +223,7 @@ detailBody dtable ( set::cols(array_values($config->task->dtable->children->fieldList)), + set::userMap($users), set::data($children), set::checkable(false) ) From 81936b67a751e615ce192778af63fe976e54c88b Mon Sep 17 00:00:00 2001 From: sunguangming Date: Fri, 17 Nov 2023 10:28:18 +0800 Subject: [PATCH 114/235] * Change color of card title. --- module/execution/css/taskkanban.ui.css | 1 + 1 file changed, 1 insertion(+) diff --git a/module/execution/css/taskkanban.ui.css b/module/execution/css/taskkanban.ui.css index 6aaae45f81..80c9d33f99 100644 --- a/module/execution/css/taskkanban.ui.css +++ b/module/execution/css/taskkanban.ui.css @@ -1,3 +1,4 @@ +.card-title { color: var(--color-black-rgb); } .toolbar .btn-link{color: unset; text-decoration-line: unset;} .toolbar .kanbanSetting.btn-link .caret{display: none;} .dropdown-menu .menu-divider a{display:none;} From 198089a78a2226abaa9366337c543792065c1286 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Fri, 17 Nov 2023 10:30:11 +0800 Subject: [PATCH 115/235] * Change WIP style. --- module/execution/css/taskkanban.ui.css | 1 + 1 file changed, 1 insertion(+) diff --git a/module/execution/css/taskkanban.ui.css b/module/execution/css/taskkanban.ui.css index 80c9d33f99..b4822dea08 100644 --- a/module/execution/css/taskkanban.ui.css +++ b/module/execution/css/taskkanban.ui.css @@ -4,3 +4,4 @@ .dropdown-menu .menu-divider a{display:none;} .dropdown-menu .menu-divider {border-top:1px solid #dedede;} .kanban-header-col-actions{top:unset;} +.as-subtitle {color: rgb(139, 145, 162); opacity: 0.5; text-wrap: nowrap; font-weight: 700;} From a670e5b83118166d93053cb4635bfbbb2391eb3a Mon Sep 17 00:00:00 2001 From: wangyidong Date: Fri, 17 Nov 2023 10:30:59 +0800 Subject: [PATCH 116/235] * Add test unit for account browse page. --- module/account/control.php | 9 +++--- module/account/model.php | 11 +++---- module/account/test/model/getlist.php | 27 ++++++++++++++++ module/search/model.php | 6 ++-- test/data/account.yaml | 44 +++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 module/account/test/model/getlist.php create mode 100644 test/data/account.yaml diff --git a/module/account/control.php b/module/account/control.php index 58380d3261..17566c67b7 100644 --- a/module/account/control.php +++ b/module/account/control.php @@ -14,16 +14,16 @@ class account extends control /** * Browse accouts page. * - * @param string $browseType - * @param string $param - * @param string $orderBy + * @param string $browseType + * @param string $param + * @param string $orderBy * @param int $recTotal * @param int $recPerPage * @param int $pageID * @access public * @return void */ - public function browse($browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function browse(string $browseType = 'all', string $param = '', string $orderBy = 'id_desc', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1) { $this->app->loadLang('serverroom'); $browseType = strtolower($browseType); @@ -47,7 +47,6 @@ class account extends control $this->view->param = $param; $this->view->orderBy = $orderBy; $this->view->browseType = $browseType; - $this->view->position[] = $this->lang->account->common; $this->display(); } diff --git a/module/account/model.php b/module/account/model.php index 78ccf07232..0c95d7738d 100644 --- a/module/account/model.php +++ b/module/account/model.php @@ -45,25 +45,22 @@ class accountModel extends model * @access public * @return array */ - public function getList($browseType = 'all', $param = 0, $orderBy = 't1.id_desc', $pager = null) + public function getList(string $browseType = 'all', string $param = '', string $orderBy = 'id_desc', object|null $pager = null) { - $query = ''; + $query = ''; if($browseType == 'bysearch') { /* Concatenate the conditions for the query. */ + if(!$this->session->accountQuery) $this->session->set('accountQuery', ' 1 = 1'); if($param) { - $query = $this->loadModel('search')->getZinQuery($param); + $query = $this->loadModel('search')->getQuery((int)$param); if($query) { $this->session->set('accountQuery', $query->sql); $this->session->set('accountForm', $query->form); } } - else - { - if(!$this->session->accountQuery) $this->session->set('accountQuery', ' 1 = 1'); - } $query = $this->session->accountQuery; } diff --git a/module/account/test/model/getlist.php b/module/account/test/model/getlist.php new file mode 100644 index 0000000000..50e4a1e2ef --- /dev/null +++ b/module/account/test/model/getlist.php @@ -0,0 +1,27 @@ +#!/usr/bin/env php +gen(5); +zdTable('account')->gen(10); +zdTable('userquery')->gen(1); + +/** + +title=accountModel->getList(); +timeout=0 +cid=1 + +*/ + +global $tester; +$accountModel = $tester->loadModel('account'); +r(count($accountModel->getList())) && p() && e('10'); // 获取所有数据。 +r(count($accountModel->getList('bysearch', '0'))) && p() && e('10'); // 根据搜索条件搜索。 +r(count($accountModel->getList('bysearch', '1'))) && p() && e('0'); // 根据第一个保存条件搜索。 + +$accountModel->app->loadClass('pager', $static = true); +$pager = new pager(0, 5, 1); +r(count($accountModel->getList('all', '', 'id_desc', $pager))) && p() && e('5'); // 分页,每页5条,获取第一页。 diff --git a/module/search/model.php b/module/search/model.php index 928d576f46..895ce0affd 100644 --- a/module/search/model.php +++ b/module/search/model.php @@ -378,16 +378,16 @@ class searchModel extends model * @access public * @return object */ - public function getQuery($queryID) + public function getQuery(int $queryID): object { - $query = $this->dao->findByID((int)$queryID)->from(TABLE_USERQUERY)->fetch(); + $query = $this->dao->findByID($queryID)->from(TABLE_USERQUERY)->fetch(); if(!$query) return false; /* Decode html encode. */ $query->form = htmlspecialchars_decode($query->form, ENT_QUOTES); $query->sql = htmlspecialchars_decode($query->sql, ENT_QUOTES); - $hasDynamic = strpos($query->form, '$') !== false; + $hasDynamic = str_contains($query->form, '$'); $query->form = unserialize($query->form); if($hasDynamic) { diff --git a/test/data/account.yaml b/test/data/account.yaml new file mode 100644 index 0000000000..70631690f7 --- /dev/null +++ b/test/data/account.yaml @@ -0,0 +1,44 @@ +title: table zt_account +desc: "运维账号" +author: automated export +version: "1.0" +fields: + - field: id + range: 1-10000 + - field: name + prefix: 运维账号 + range: 1-10000 + - field: type + range: "``" + - field: provider + range: qingyun,tencent,aliyun,azure,local,westcn + - field: adminURI + range: "``" + - field: account + note: "管理员" + prefix: user + range: 1-10000 + postfix: "@cnezsoft.com" + - field: email + prefix: user + range: 1-10000 + postfix: "@cnezsoft.com" + - field: createdBy + note: "用户名" + fields: + - field: account1 + range: admin,user{99},test{100},dev{100},pm{100},po{100},td{100},pd{100},qd{100},top{100},outside{100},others{100},a,bb,ccc,qwuiadsd?!2as@#%$aasd~aj1!@#1 + - field: account2 + range: "[],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4}" + - field: createdDate + range: "(-1M)-(+1w):-1D" + type: timestamp + format: "YYYY-MM-DD hh:mm:ss" + - field: password + range: "``" + - field: mobile + range: "``" + - field: extra + range: "``" + - field: status + range: "``" From 701fae025456c0443a92da45029d5565b90af621 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 17 Nov 2023 10:35:19 +0800 Subject: [PATCH 117/235] * Update purpose of task hour summary metric. --- module/metric/calc/system/{scale => hour}/consume_of_task.php | 2 +- module/metric/calc/system/{scale => hour}/estimate_of_task.php | 2 +- module/metric/calc/system/{scale => hour}/left_of_task.php | 2 +- .../metric/test/calc/system/{scale => hour}/consume_of_task.php | 0 .../test/calc/system/{scale => hour}/estimate_of_task.php | 0 module/metric/test/calc/system/{scale => hour}/left_of_task.php | 0 6 files changed, 3 insertions(+), 3 deletions(-) rename module/metric/calc/system/{scale => hour}/consume_of_task.php (98%) rename module/metric/calc/system/{scale => hour}/estimate_of_task.php (98%) rename module/metric/calc/system/{scale => hour}/left_of_task.php (98%) rename module/metric/test/calc/system/{scale => hour}/consume_of_task.php (100%) rename module/metric/test/calc/system/{scale => hour}/estimate_of_task.php (100%) rename module/metric/test/calc/system/{scale => hour}/left_of_task.php (100%) diff --git a/module/metric/calc/system/scale/consume_of_task.php b/module/metric/calc/system/hour/consume_of_task.php similarity index 98% rename from module/metric/calc/system/scale/consume_of_task.php rename to module/metric/calc/system/hour/consume_of_task.php index d2d7c0a75d..692d061915 100755 --- a/module/metric/calc/system/scale/consume_of_task.php +++ b/module/metric/calc/system/hour/consume_of_task.php @@ -5,7 +5,7 @@ * * 范围:system * 对象:task - * 目的:scale + * 目的:hour * 度量名称:按系统统计的任务消耗工时数 * 单位:小时 * 描述:按系统统计的任务消耗工时数是指已经花费的工时总和,用于完成所有任务。该度量项可以用来评估团队或组织在任务执行过程中的工时投入情况,以及在完成任务方面的效率和资源利用情况。较高的任务消耗工时总数可能表明需要审查工作流程和资源分配,以提高工作效率。 diff --git a/module/metric/calc/system/scale/estimate_of_task.php b/module/metric/calc/system/hour/estimate_of_task.php similarity index 98% rename from module/metric/calc/system/scale/estimate_of_task.php rename to module/metric/calc/system/hour/estimate_of_task.php index 465e79f5aa..3be2168f81 100755 --- a/module/metric/calc/system/scale/estimate_of_task.php +++ b/module/metric/calc/system/hour/estimate_of_task.php @@ -5,7 +5,7 @@ * * 范围:system * 对象:task - * 目的:scale + * 目的:hour * 度量名称:按系统统计的任务预计工时数 * 单位:小时 * 描述:按系统统计的任务预计工时数是指所有任务预计完成所需的工时总和。该度量项可以用来规划资源和预估工期,为项目管理和团队协作提供依据。较准确的任务预计工时总数可以帮助团队更好地安排时间和资源,提高任务的完成效率。 diff --git a/module/metric/calc/system/scale/left_of_task.php b/module/metric/calc/system/hour/left_of_task.php similarity index 98% rename from module/metric/calc/system/scale/left_of_task.php rename to module/metric/calc/system/hour/left_of_task.php index 4399b14bde..9848410957 100755 --- a/module/metric/calc/system/scale/left_of_task.php +++ b/module/metric/calc/system/hour/left_of_task.php @@ -5,7 +5,7 @@ * * 范围:system * 对象:task - * 目的:scale + * 目的:hour * 度量名称:按系统统计的任务剩余工时数 * 单位:小时 * 描述:按系统统计的任务剩余工时数是指任务当前剩余工时的总和,用于完成所有任务。该度量项可以用来评估团队或组织在任务执行过程中剩余的工作量和时间,以及为完成任务所需的资源和计划。较小的任务剩余工时总数可能表示团队即将完成任务。 diff --git a/module/metric/test/calc/system/scale/consume_of_task.php b/module/metric/test/calc/system/hour/consume_of_task.php similarity index 100% rename from module/metric/test/calc/system/scale/consume_of_task.php rename to module/metric/test/calc/system/hour/consume_of_task.php diff --git a/module/metric/test/calc/system/scale/estimate_of_task.php b/module/metric/test/calc/system/hour/estimate_of_task.php similarity index 100% rename from module/metric/test/calc/system/scale/estimate_of_task.php rename to module/metric/test/calc/system/hour/estimate_of_task.php diff --git a/module/metric/test/calc/system/scale/left_of_task.php b/module/metric/test/calc/system/hour/left_of_task.php similarity index 100% rename from module/metric/test/calc/system/scale/left_of_task.php rename to module/metric/test/calc/system/hour/left_of_task.php From 280fbc052cc60fe8b7663b3738967448257ed114 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Fri, 17 Nov 2023 10:37:52 +0800 Subject: [PATCH 118/235] * Adjust file open errror. --- module/repo/js/monaco.ui.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/repo/js/monaco.ui.js b/module/repo/js/monaco.ui.js index 5688e77ffe..d918e5f8e7 100644 --- a/module/repo/js/monaco.ui.js +++ b/module/repo/js/monaco.ui.js @@ -86,8 +86,9 @@ window.afterPageUpdate = function() */ window.treeClick = function(info) { - if (info.item.items && info.item.items.length > 0) return; - $('#' + info.item.id).parent().addClass('selected'); + if(info.item.items && (info.item.items.length > 0 || info.item.items.url)) return; + + $('li[z-key="' + info.item.id + '"]').addClass('selected'); openTab(info.item.key, info.item.text); arrowTabs('monacoTabs', -2); } From ad2b8ef35b341c266b627ca65f857f689027201d Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 17 Nov 2023 10:41:58 +0800 Subject: [PATCH 119/235] Revert "* project: change the project to long term project if the end date is greater than or equal to the const LONG_TIME." This reverts commit bc751d458bfe53af52b4f23536f264a496224312. --- module/project/js/common.ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index d308cc30cf..d8c6d5dad6 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -87,10 +87,10 @@ function computeWorkDays() const begin = $('#begin').zui('datePicker').$.state.value; const end = $('#end').zui('datePicker').$.state.value; - if(end >= LONG_TIME) + if(end == LONG_TIME) { $('#delta999').prop('checked', true); - computeEndDate(); + $('#days').val(0).trigger('change'); } else { From 04797feca3c665fa0dffc10d7d7b851b86515d30 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 10:45:07 +0800 Subject: [PATCH 120/235] * Change to new writing method. --- module/bug/ui/batchcreate.html.php | 2 +- module/bug/ui/create.html.php | 62 ++++++++++++++++-------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/module/bug/ui/batchcreate.html.php b/module/bug/ui/batchcreate.html.php index 5286ae6a57..524083d2f9 100644 --- a/module/bug/ui/batchcreate.html.php +++ b/module/bug/ui/batchcreate.html.php @@ -19,7 +19,7 @@ if(isset($executionType) && $executionType == 'kanban') } $bugs = array(); -if($titles) +if(!empty($titles)) { foreach($titles as $title => $fileName) { diff --git a/module/bug/ui/create.html.php b/module/bug/ui/create.html.php index 9fb1cd4b3a..12ee32c9bc 100644 --- a/module/bug/ui/create.html.php +++ b/module/bug/ui/create.html.php @@ -40,7 +40,7 @@ formPanel formGroup ( set::width('1/2'), - set::className($product->shadow ? 'hidden' : ''), + setClass($product->shadow ? 'hidden' : ''), set::label($lang->bug->product), inputGroup ( @@ -67,7 +67,7 @@ formPanel set::required(strpos(",{$config->bug->create->requiredFields},", ',project,') !== false), inputGroup ( - set('id', 'projectBox'), + setID('projectBox'), picker ( set::name('project'), @@ -86,7 +86,7 @@ formPanel set::required(strpos(",{$config->bug->create->requiredFields},", ',module,') !== false), inputGroup ( - set('id', 'moduleBox'), + setID('moduleBox'), picker ( set::name('module'), @@ -96,19 +96,25 @@ formPanel ), count($moduleOptionMenu) == 1 ? span ( - set('class', 'input-group-addon'), + setClass('input-group-addon'), a ( - set('class', 'mr-2'), + setClass('mr-2'), set('href', $this->createLink('tree', 'browse', "rootID=$bug->productID&view=bug¤tModuleID=0&branch={$bug->branch}")), - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setData + ( + array + ( + 'toggle' => 'modal', + 'size' => 'lg' + ) + ), $lang->tree->manage ), a ( - set('id', 'refreshModule'), - set('class', 'text-black'), + setID('refreshModule'), + setClass('text-black'), set('href', 'javascript:void(0)'), icon('refresh') ) @@ -118,7 +124,7 @@ formPanel formGroup ( set::width('1/2'), - set('id', 'executionBox'), + setID('executionBox'), set::label($bug->projectModel == 'kanban' ? $lang->bug->kanban : $lang->bug->execution), set::required(strpos(",{$config->bug->create->requiredFields},", ',execution,') !== false), picker @@ -142,23 +148,23 @@ formPanel ( set::multiple(true), set::name('openedBuild[]'), - set('data-items', count($builds)), set::items($builds), - set::value(empty($bug->buildID) ? 'trunk' : $bug->buildID) + set::value(empty($bug->buildID) ? 'trunk' : $bug->buildID), + setData(array('items' => count($builds))) ), span ( - set('id', 'buildBoxActions'), - set('class', 'input-group-addon'), + setID('buildBoxActions'), + setClass('input-group-addon'), setStyle(array('display' => 'none')) ), span ( - set('class', 'input-group-btn'), + setClass('input-group-btn'), a ( setClass('btn'), - set('id', 'allBuilds'), + setID('allBuilds'), set('href', 'javascript:;'), $lang->bug->loadAll ) @@ -179,11 +185,11 @@ formPanel ), span ( - set('class', 'input-group-btn'), + setClass('input-group-btn'), a ( setClass('btn'), - set('id', 'allUsers'), + setID('allUsers'), set('href', 'javascript:;'), $lang->bug->loadAll ) @@ -221,7 +227,7 @@ formPanel set::required(strpos(",{$config->bug->create->requiredFields},", ',deadline,') !== false), datePicker ( - set::id('deadline'), + setID('deadline'), set::name('deadline'), set::value($bug->deadline) ) @@ -344,7 +350,7 @@ formPanel set::label($lang->bug->story), inputGroup ( - set('id', 'storyBox'), + setID('storyBox'), picker ( set::name('story'), @@ -380,12 +386,12 @@ formPanel ), span ( - set('id', 'contactBox'), - set('class', 'input-group-addon'), + setID('contactBox'), + setClass('input-group-addon'), $contactList ? setStyle(array('width' => '100px', 'padding' => '0')) : null, $contactList ? picker ( - set::className('width', 'w-20'), + setClass('w-20'), set::name('contactListMenu'), set::items($contactList), set::value(), @@ -393,19 +399,19 @@ formPanel ) : span ( - set('class', 'input-group-addon'), + setClass('input-group-addon'), a ( - set('class', 'mr-2'), + setClass('mr-2'), + setData(array('toggle' => 'modal')), set('href', createLink('my', 'managecontacts', 'listID=0&mode=new')), set('title', $lang->user->contacts->manage), - set('data-toggle', 'modal'), icon('cog') ), a ( - set('id', 'refreshMailto'), - set('class', 'text-black'), + setID('refreshMailto'), + setClass('text-black'), set('href', 'javascript:void(0)'), icon('refresh') ) From 3a416e129cb9455c0b82464bbbfc390fcf507395 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Fri, 17 Nov 2023 10:45:18 +0800 Subject: [PATCH 121/235] * Optimize gitlab directory tree loading speed. --- module/gitlab/model.php | 18 +++++ module/repo/control.php | 16 ++++ module/repo/model.php | 130 +++++++++++++++++++++++++-------- module/repo/ui/monaco.html.php | 9 ++- 4 files changed, 140 insertions(+), 33 deletions(-) diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 445d0873b5..210da4086c 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -3055,4 +3055,22 @@ class gitlabModel extends model return true; } + + /** + * Get data by api graphql. + * + * @param int $gitlabID + * @param int $query + * @access public + * @return object|null + */ + public function apiGetByGraphql(int $gitlabID, array $query): object|null + { + static $gitlab; + if(empty($gitlab)) $gitlab = $this->getByID($gitlabID); + if(!$gitlab) return array(); + + $url = rtrim($gitlab->url, '/') . '/api/graphql' . "?private_token={$gitlab->token}"; + return json_decode(commonModel::http($url, $query)); + } } diff --git a/module/repo/control.php b/module/repo/control.php index 02eaf042c4..5d71129b13 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -1980,4 +1980,20 @@ class repo extends control echo ''; } } + + /** + * Get gitlab files. + * + * @param int $repoID + * @param string $branch + * @param string $path + * @access public + * @return string + */ + public function ajaxGetFiles(int $repoID, string $branch = '', string $path = '') + { + $repo = $this->repo->getByID($repoID); + if($path) $path = helper::safe64Decode($path); + echo json_encode($this->repo->getGitlabFilesByPath($repo, $path, $branch)); + } } diff --git a/module/repo/model.php b/module/repo/model.php index ac98abd653..545782eb13 100644 --- a/module/repo/model.php +++ b/module/repo/model.php @@ -2442,8 +2442,9 @@ class repoModel extends model * @access public * @return array */ - public function getFileList($repo, $branch, $path = '') + public function getFileList($repo, $branch = '', $path = '') { + $_COOKIE['repoBranch'] = $branch ? $branch : $this->cookie->repoBranch; $scm = $this->app->loadClass('scm'); $scm->setEngine($repo); @@ -2532,43 +2533,43 @@ class repoModel extends model } else { - if($repo->SCM != 'Subversion' and empty($branch)) $branch = $this->cookie->repoBranch; - $files = $this->dao->select('t1.path,t2.time,t1.action')->from(TABLE_REPOFILES)->alias('t1') - ->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.revision=t2.id') - ->leftJoin(TABLE_REPOBRANCH)->alias('t3')->on('t2.id=t3.revision') - ->where('t1.repo')->eq($repo->id) - ->andWhere('t1.type')->eq('file') - ->andWhere('left(t2.`comment`, 12)')->ne('Merge branch') - ->beginIF($repo->SCM != 'Subversion' and $branch)->andWhere('t3.branch')->eq($branch)->fi() - ->orderBy('t2.`time` asc') - ->fetchAll('path'); - - $removeDirs = array(); - if($repo->SCM == 'Subversion') - { - $removeDirs = $this->dao->select('t2.time,t1.path')->from(TABLE_REPOFILES)->alias('t1') + if($repo->SCM != 'Subversion' and empty($branch)) $branch = $this->cookie->repoBranch; + $files = $this->dao->select('t1.path,t2.time,t1.action')->from(TABLE_REPOFILES)->alias('t1') ->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.revision=t2.id') + ->leftJoin(TABLE_REPOBRANCH)->alias('t3')->on('t2.id=t3.revision') ->where('t1.repo')->eq($repo->id) - ->andWhere('t1.type')->eq('dir') - ->andWhere('t1.action')->eq('D') - ->fetchPairs(); + ->andWhere('t1.type')->eq('file') + ->andWhere('left(t2.`comment`, 12)')->ne('Merge branch') + ->beginIF($repo->SCM != 'Subversion' and $branch)->andWhere('t3.branch')->eq($branch)->fi() + ->orderBy('t2.`time` asc') + ->fetchAll('path'); - } - foreach($files as $file) - { - foreach($removeDirs as $removeTime => $dir) + $removeDirs = array(); + if($repo->SCM == 'Subversion') { - if(strpos($file->path, $dir . '/') === 0 and $file->time <= $removeTime) + $removeDirs = $this->dao->select('t2.time,t1.path')->from(TABLE_REPOFILES)->alias('t1') + ->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.revision=t2.id') + ->where('t1.repo')->eq($repo->id) + ->andWhere('t1.type')->eq('dir') + ->andWhere('t1.action')->eq('D') + ->fetchPairs(); + + } + foreach($files as $file) + { + foreach($removeDirs as $removeTime => $dir) { - $file->action = 'D'; - break; + if(strpos($file->path, $dir . '/') === 0 and $file->time <= $removeTime) + { + $file->action = 'D'; + break; + } + } + if($file->action != 'D') + { + $allFiles[] = $file->path; } } - if($file->action != 'D') - { - $allFiles[] = $file->path; - } - } } } else @@ -2616,7 +2617,6 @@ class repoModel extends model } } sort($files); - return $this->buildTree($files); } @@ -3223,4 +3223,70 @@ class repoModel extends model return !dao::isError(); } + + /** + * 根据路径获取gitlab文件列表。 + * Get gitlab files by path. + * + * @param object $repo + * @param string $path + * @param string $branch + * @access public + * @return array + */ + public function getGitlabFilesByPath(object $repo, string $path = '', string $branch = ''): array + { + if(!$branch) $branch = $this->cookie->branch; + + $fullPath = trim(str_replace($repo->client, '', $repo->codePath), '/'); + $query = array('query' => 'query { project(fullPath: "' . $fullPath . '") {repository {tree(path: "' . trim($path, '/') . '", ref: "' . $branch . '") {trees {nodes {name path}} blobs {nodes {name path}}}}}}'); + $response = $this->loadModel('gitlab')->apiGetByGraphql($repo->serviceHost, $query); + if(!isset($response->data->project->repository)) return array(); + + $folderList = $response->data->project->repository->tree->trees->nodes; + $fileList = $response->data->project->repository->tree->blobs->nodes; + + $files = array(); + $folders = array(); + $dirList = array(); + $fileSort = $dirSort = array(); // Use it to sort array. + + foreach($fileList as $file) + { + $base64Name = base64_encode($file->path); + + $fileInfo = new stdclass(); + $fileInfo->id = $base64Name; + $fileInfo->name = $file->name; + $fileInfo->text = $file->name; + $fileInfo->path = $file->path; + $fileInfo->key = $base64Name; + $fileInfo->kind = 'file'; + + $files[] = $fileInfo; + $fileSort[] = $file->name; + } + + foreach($folderList as $dir) + { + $base64Name = base64_encode($dir->path); + + $folder = new stdclass(); + $folder->id = $base64Name; + $folder->name = $dir->name; + $folder->text = $dir->name; + $folder->path = $dir->path; + $folder->key = $base64Name; + $folder->kind = 'dir'; + $folder->items = array('url' => helper::createLink('repo', 'ajaxGetFiles', "repoID={$repo->id}&branch={$branch}&path=" . helper::safe64Encode($dir->path))); + + $dirList[] = $dir->name; + $folders[] = $folder; + $dirSort[] = $dir->name; + } + array_multisort($fileSort, SORT_ASC, $files); + array_multisort($dirSort, SORT_ASC, $folders); + + return array_merge($folders, $files); + } } diff --git a/module/repo/ui/monaco.html.php b/module/repo/ui/monaco.html.php index f7efeeb99a..d47201f820 100644 --- a/module/repo/ui/monaco.html.php +++ b/module/repo/ui/monaco.html.php @@ -20,7 +20,14 @@ dropmenu set::url(createLink($module, 'ajaxGetDropMenu', "objectID=$objectID&module={$app->rawModule}&method={$app->rawMethod}")) ); -$tree = $this->repo->getFileTree($repo); +if($repo->SCM == 'Gitlab') +{ + $tree = $this->repo->getGitlabFilesByPath($repo, '', (string)$branchID); +} +else +{ + $tree = $this->repo->getFileTree($repo); +} jsVar('isonlybody', isonlybody()); jsVar('entry', $entry); From 08f426893d5e975c59f5f91a45d6ab2f552910c8 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 10:43:58 +0800 Subject: [PATCH 122/235] * Fix create a bug navgation when the system don't have any product. --- module/bug/control.php | 2 +- module/product/ui/showerrornone.html.php | 2 +- module/product/zen.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index 67c30f079a..741913b13d 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -73,7 +73,7 @@ class bug extends control $products = $this->product->getPairs($mode, 0, '', 'all'); } - if(empty($products) and !helper::isAjaxRequest()) $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=bug&objectID=$objectID")); + if(empty($products) and substr($this->app->rawMethod, 0, 4) != 'ajax') $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=bug&objectID=$objectID")); } else { diff --git a/module/product/ui/showerrornone.html.php b/module/product/ui/showerrornone.html.php index efd1acadaf..320950e530 100644 --- a/module/product/ui/showerrornone.html.php +++ b/module/product/ui/showerrornone.html.php @@ -42,7 +42,7 @@ div ( setClass('btn ghost text-primary'), set::href($link), - set('data-app', $app->tab), + setData('app', $tab), icon('plus'), $text ) diff --git a/module/product/zen.php b/module/product/zen.php index 6a57bcb75e..ffa9b85d43 100644 --- a/module/product/zen.php +++ b/module/product/zen.php @@ -530,10 +530,10 @@ class productZen extends product $moduleName = $tab == 'program' ? 'program' : $this->moduleName; $methodName = $tab == 'program' ? 'product' : 'browse'; $param = $tab == 'program' ? "programID=$programID" : "productID=$productID"; - $location = isonlybody() ? 'true' : $this->createLink($moduleName, $methodName, $param); + $location = isInModal() ? 'true' : $this->createLink($moduleName, $methodName, $param); if($tab == 'doc') $location = $this->createLink('doc', 'productSpace', "objectID=$productID"); - return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => $location); + return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => $location, 'closeModal' => true); } /** From 5702b706f82bfd5e4d3706b98d4c909e68e9ef6f Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 17 Nov 2023 10:47:05 +0800 Subject: [PATCH 123/235] * project: display work days in batch edit page. --- module/project/ui/batchedit.html.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/module/project/ui/batchedit.html.php b/module/project/ui/batchedit.html.php index 9eb71cee70..0adf36075b 100644 --- a/module/project/ui/batchedit.html.php +++ b/module/project/ui/batchedit.html.php @@ -45,13 +45,12 @@ formBatchPanel set::label($lang->project->program), set::control('picker'), set::items($programs), - set::width('128px') + set::width('136px') ), formBatchItem ( set::name('name'), set::label($lang->project->name), - set::width('240px') ), $setCode ? formBatchItem ( @@ -74,13 +73,19 @@ formBatchPanel set::name('begin'), set::label($lang->project->begin), set::control('date'), - set::width('84px') + set::width('120px') ), formBatchItem ( set::name('end'), set::label($lang->project->end), set::control('date'), + set::width('120px') + ), + formBatchItem + ( + set::name('days'), + set::label($lang->project->days), set::width('84px') ), formBatchItem From fc2630fdf13332f7e592bd464a51bd80597882ad Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 17 Nov 2023 10:53:56 +0800 Subject: [PATCH 124/235] * project: if a project is a long-term project, update the style of the planned completion date and available working days. --- module/project/js/batchedit.ui.js | 8 ++++++++ module/project/ui/batchedit.html.php | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/module/project/js/batchedit.ui.js b/module/project/js/batchedit.ui.js index baccaf35da..3ba39d6b93 100644 --- a/module/project/js/batchedit.ui.js +++ b/module/project/js/batchedit.ui.js @@ -1,5 +1,13 @@ window.renderRowData = function($row, index, row) { + /* 如果某个项目是长期项目,更新计划完成日期和可用工作日的样式。*/ + /* If a project is a long-term project, update the style of the planned completion date and available working days. */ + if(row.end == LONG_TIME) + { + $row.find('[data-name="end"] [id^=end]').attr('data-longTime', 1).addClass('hidden').next().removeClass('hidden'); + $row.find('[name^=days]').val(0).attr('readonly', true); + } + const aclList = !disabledprograms && row.parent ? programAclList : projectAclList; $row.find('[data-name="acl"]').find('.picker-box').on('inited', function(e, info) { diff --git a/module/project/ui/batchedit.html.php b/module/project/ui/batchedit.html.php index 0adf36075b..4d17772c6d 100644 --- a/module/project/ui/batchedit.html.php +++ b/module/project/ui/batchedit.html.php @@ -15,6 +15,7 @@ $projectAclList = array(); foreach($lang->program->subAcls as $acl => $label) $programAclList[] = array('text' => $label, 'value' => $acl); foreach($lang->project->acls as $acl => $label) $projectAclList[] = array('text' => $label, 'value' => $acl); +jsVar('LONG_TIME', LONG_TIME); jsVar('programAclList', $programAclList); jsVar('projectAclList', $projectAclList); jsVar('disabledprograms', !empty($globalDisableProgram)); @@ -80,7 +81,17 @@ formBatchPanel set::name('end'), set::label($lang->project->end), set::control('date'), - set::width('120px') + set::width('120px'), + inputControl + ( + setClass('has-suffix-icon hidden'), + to::suffix(icon('calendar')), + input + ( + set::value($lang->project->longTime), + set::disabled(true) + ) + ) ), formBatchItem ( From 320ccda40abf785857c391a048c1782a4579e084 Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 17 Nov 2023 10:56:11 +0800 Subject: [PATCH 125/235] * project: compute working days if the begin date or end date changes. --- module/project/js/batchedit.ui.js | 17 +++++++++++++++++ module/project/ui/batchedit.html.php | 2 ++ 2 files changed, 19 insertions(+) diff --git a/module/project/js/batchedit.ui.js b/module/project/js/batchedit.ui.js index 3ba39d6b93..299733a508 100644 --- a/module/project/js/batchedit.ui.js +++ b/module/project/js/batchedit.ui.js @@ -1,3 +1,20 @@ +/** + * 更新可用工作日天数。 + * Update work days. + * + * @access public + * @return void + */ +function batchComputeWorkDays() +{ + if($(this).closest('tr').find('div[data-longtime="1"]').length > 0) return false; + + const index = $(this).attr('name').replace(/(begin\[)|(end\[)|(\])/g, ''); + const beginDate = $('[name=begin\\[' + index + '\\]').val(); + const endDate = $('[name=end\\[' + index + '\\]').val(); + $('[name=days\\[' + index + '\\]').val(computeDaysDelta(beginDate, endDate)); +} + window.renderRowData = function($row, index, row) { /* 如果某个项目是长期项目,更新计划完成日期和可用工作日的样式。*/ diff --git a/module/project/ui/batchedit.html.php b/module/project/ui/batchedit.html.php index 4d17772c6d..78a8b6edd0 100644 --- a/module/project/ui/batchedit.html.php +++ b/module/project/ui/batchedit.html.php @@ -16,6 +16,7 @@ foreach($lang->program->subAcls as $acl => $label) $programAclList[] = array('te foreach($lang->project->acls as $acl => $label) $projectAclList[] = array('text' => $label, 'value' => $acl); jsVar('LONG_TIME', LONG_TIME); +jsVar('weekend', $config->execution->weekend); jsVar('programAclList', $programAclList); jsVar('projectAclList', $projectAclList); jsVar('disabledprograms', !empty($globalDisableProgram)); @@ -26,6 +27,7 @@ formBatchPanel set::mode('edit'), set::data(array_values($projects)), set::onRenderRow(jsRaw('renderRowData')), + on::change('[name^=begin],[name^=end]', 'batchComputeWorkDays'), formBatchItem ( set::name('id'), From c0140c968ce24089022c3aab2d005fbc2e503b6b Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 10:57:28 +0800 Subject: [PATCH 126/235] * Add tooltips to qastatistic block, and modify style of tooltips in statistic block. --- module/block/lang/zh-cn.php | 7 +++---- module/block/ui/executionstatisticblock.html.php | 6 +++--- module/block/ui/productstatisticblock.html.php | 5 +++-- module/block/ui/projectstatisticblock.html.php | 13 ++++++++++--- module/block/ui/qastatisticblock.html.php | 16 +++++++++++++++- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index e7feed70f8..dee0724386 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -589,9 +589,7 @@ $lang->block->projectstatistic->lastestExecution = '最新执行'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon}已关闭"; $lang->block->projectstatistic->longTimeProject = "长期{$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = '总进度'; -$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数/(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)\n -按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。\n -按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。"; +$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数/(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)
按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。
按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。"; $lang->block->projectstatistic->currentCost = '当前成本'; $lang->block->projectstatistic->sv = '进度偏差率(SV)'; $lang->block->projectstatistic->pv = '计划完成(PV)'; @@ -716,4 +714,5 @@ $lang->block->tooltips['ev'] = "实际完成=按项目统计的 $lang->block->tooltips['pv'] = '计划完成:瀑布项目中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的执行的任务,过滤已删除的项目。'; $lang->block->tooltips['cv'] = '成本偏差率=(EV-AC)/AC*100%'; $lang->block->tooltips['ac'] = '实际花费:瀑布项目中所有日志记录的工时之和,过滤已删除的项目。'; -$lang->block->tooltips['executionProgress'] = "执行进度=按执行统计的任务消耗工时数/(按执行统计的任务消耗工时数+按执行统计的任务剩余工时数)\n 按执行统计的任务消耗工时数:执行中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。\n 按执行统计的任务剩余工时数:执行中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。"; +$lang->block->tooltips['executionProgress'] = "执行进度=按执行统计的任务消耗工时数/(按执行统计的任务消耗工时数+按执行统计的任务剩余工时数)
按执行统计的任务消耗工时数:执行中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。
按执行统计的任务剩余工时数:执行中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。"; +$lang->block->tooltips['closedBugRate'] = "Bug修复率=按产品统计的已修复Bug数/按产品统计的有效Bug数。
按产品统计的已修复Bug数:产品中Bug的个数求和,解决方案为已解决,状态为已关闭,过滤已删除的Bug,过滤已删除的产品。
按产品统计的有效Bug数:产品中所有Bug个数求和,解决方案为已解决、延期处理或状态为激活,过滤已删除的Bug,过滤已删除的产品。"; diff --git a/module/block/ui/executionstatisticblock.html.php b/module/block/ui/executionstatisticblock.html.php index f8fc5adadf..a599e1aab0 100644 --- a/module/block/ui/executionstatisticblock.html.php +++ b/module/block/ui/executionstatisticblock.html.php @@ -137,18 +137,18 @@ statisticBlock $lang->block->executionstatistic->progress, icon ( - 'help', + setClass('text-light ml-0.5 text-sm'), toggle::tooltip ( array ( - 'title' => $lang->block->tooltips['executionProgress'], + 'content' => array('html' => $lang->block->tooltips['executionProgress']), 'placement' => 'bottom', 'type' => 'white', 'className' => 'text-dark border border-light leading-5' ) ), - setClass('text-light ml-0.5') + 'help' ) ) ) diff --git a/module/block/ui/productstatisticblock.html.php b/module/block/ui/productstatisticblock.html.php index 66a538cc5b..4ba47392b5 100644 --- a/module/block/ui/productstatisticblock.html.php +++ b/module/block/ui/productstatisticblock.html.php @@ -80,7 +80,7 @@ statisticBlock $lang->block->productstatistic->deliveryRate, icon ( - 'help', + setClass('text-light text-sm'), toggle::tooltip ( array @@ -90,7 +90,8 @@ statisticBlock 'type' => 'white', 'className' => 'text-dark border border-light leading-5' ) - ) + ), + 'help' ) ) ), diff --git a/module/block/ui/projectstatisticblock.html.php b/module/block/ui/projectstatisticblock.html.php index 6a67dc7f23..6e3c6e402d 100644 --- a/module/block/ui/projectstatisticblock.html.php +++ b/module/block/ui/projectstatisticblock.html.php @@ -120,7 +120,7 @@ if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) ( isset($lang->block->tooltips[$field]) ? icon ( - 'help', + setClass('text-light text-sm'), toggle::tooltip ( array @@ -131,6 +131,7 @@ if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) 'className' => 'text-dark border border-light leading-5' ) ), + 'help', ':' ) : null ), @@ -189,12 +190,12 @@ else $lang->block->projectstatistic->totalProgress, icon ( - setClass('pl-0.5'), + setClass('pl-0.5 text-light text-sm'), toggle::tooltip ( array ( - 'title' => $lang->block->projectstatistic->totalProgressTip, + 'content' => array('html' => $lang->block->projectstatistic->totalProgressTip), 'placement' => 'bottom', 'type' => 'white', 'className' => 'text-dark border border-light leading-5' @@ -228,6 +229,7 @@ else ( icon ( + setClass('text-light text-sm'), toggle::tooltip ( array @@ -255,6 +257,7 @@ else ( icon ( + setClass('text-light text-sm'), toggle::tooltip ( array @@ -282,6 +285,7 @@ else ( icon ( + setClass('text-light text-sm'), toggle::tooltip ( array @@ -326,6 +330,7 @@ else ( icon ( + setClass('text-light text-sm'), toggle::tooltip ( array @@ -353,6 +358,7 @@ else ( icon ( + setClass('text-light text-sm'), toggle::tooltip ( array @@ -380,6 +386,7 @@ else ( icon ( + setClass('text-light text-sm'), toggle::tooltip ( array diff --git a/module/block/ui/qastatisticblock.html.php b/module/block/ui/qastatisticblock.html.php index cc8a5f9395..8bcd90f27d 100644 --- a/module/block/ui/qastatisticblock.html.php +++ b/module/block/ui/qastatisticblock.html.php @@ -168,7 +168,21 @@ statisticBlock ( setClass('row text-sm text-gray items-center gap-1'), $lang->block->qastatistic->closedBugRate, - icon('help text-light text-sm') + icon + ( + 'help', + setClass('text-light text-sm'), + toggle::tooltip + ( + array + ( + 'content' => array('html' => $lang->block->tooltips['closedBugRate']), + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ) + ) ) ), row From cb29fcf9133278ddd14c72a2d12b9f4de9728372 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 11:01:08 +0800 Subject: [PATCH 127/235] * Fix create a testcase navgation when the system don't have any product. --- module/testcase/control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/testcase/control.php b/module/testcase/control.php index 1b27302127..c35ccb1cad 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -62,7 +62,7 @@ class testcase extends control $mode = ($this->app->methodName == 'create' and empty($this->config->CRProduct)) ? 'noclosed' : ''; $products = $this->product->getPairs($mode, 0, '', 'all'); } - if(empty($products) and !helper::isAjaxRequest()) return print($this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=testcase&objectID=$objectID"))); + if(empty($products) and substr($this->app->rawMethod, 0, 4) != 'ajax') $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=testcase&objectID=$objectID")); } else { From 71cca75fb680b0922bca5979f250752128253794 Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 17 Nov 2023 11:05:53 +0800 Subject: [PATCH 128/235] - project: remove unused function. --- module/project/js/common.ui.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index d8c6d5dad6..d591389ddd 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -147,19 +147,6 @@ function formatDate(dateString, days) return date.toLocaleDateString('en-CA') } -/** - * Convert a date string like 2011-11-11 to date object in js. - * - * @param string dateString - * @access public - * @return date - */ -function convertStringToDate(dateString) -{ - dateString = dateString.split('-'); - return new Date(dateString[0], dateString[1] - 1, dateString[2]); -} - /** * 提示并删除项目。 * Delete project with tips. From ef1111834377ccde1056abbf23f99dd6cabad78c Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 11:29:54 +0800 Subject: [PATCH 129/235] * refactor, rename class name tabnActions to tab-actions. --- module/build/css/view.ui.css | 2 +- module/build/ui/view.html.php | 4 ++-- module/productplan/css/view.ui.css | 4 ++-- module/productplan/ui/view.html.php | 4 ++-- module/release/css/view.ui.css | 2 +- module/release/ui/view.html.php | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/module/build/css/view.ui.css b/module/build/css/view.ui.css index c6abdccc73..5a0d3f2fde 100644 --- a/module/build/css/view.ui.css +++ b/module/build/css/view.ui.css @@ -1,2 +1,2 @@ .entity-label .id-label {border: 1px solid var(--color-slate-500) !important;} -.tabnActions {float:right; margin-top: -45px;} +.tab-actions {float:right; margin-top: -45px;} diff --git a/module/build/ui/view.html.php b/module/build/ui/view.html.php index 36cf177a32..a8f67bcd83 100644 --- a/module/build/ui/view.html.php +++ b/module/build/ui/view.html.php @@ -117,7 +117,7 @@ detailBody set::active($type == 'story'), div ( - setClass('tabnActions'), + setClass('tab-actions'), !common::hasPriv($buildModule, 'linkStory') ? null : btn(set::text($lang->build->linkStory), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'story'), set('data-linkurl', createLink($buildModule, 'linkStory', "buildID={$build->id}" . (($link == 'true' && $type == 'story') ? $decodeParam : "&browseType=¶m=")))) ), dtable @@ -147,7 +147,7 @@ detailBody set::active($type == 'bug'), div ( - setClass('tabnActions'), + setClass('tab-actions'), !common::hasPriv($buildModule, 'linkBug') ? null : btn(set::text($lang->build->linkBug), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'bug'), set('data-linkurl', createLink($buildModule, 'linkBug', "buildID={$build->id}" . (($link == 'true' && $type == 'bug') ? $decodeParam : "&browseType=¶m=")))) ), dtable diff --git a/module/productplan/css/view.ui.css b/module/productplan/css/view.ui.css index da12602bd6..b90df12f01 100644 --- a/module/productplan/css/view.ui.css +++ b/module/productplan/css/view.ui.css @@ -1,5 +1,5 @@ -.tabnActions {float:right; margin-top: -55px;} -.tabnActions .primary {margin-left:8px;} +.tab-actions {float:right; margin-top: -55px;} +.tab-actions .primary {margin-left:8px;} #mainContent .detail-body .section-list .tabs ul {border-bottom-width: 1px; border-bottom-style: solid;} #mainContent .detail-body .section-list .tab-content .table-data caption {padding-top: 16px;} #planInfo table caption {font-size: 1rem; font-weight: bold;} diff --git a/module/productplan/ui/view.html.php b/module/productplan/ui/view.html.php index 4a813d79d0..7a4e8f6eac 100644 --- a/module/productplan/ui/view.html.php +++ b/module/productplan/ui/view.html.php @@ -182,7 +182,7 @@ detailBody set::active($type == 'story'), div ( - setClass('tabnActions'), + setClass('tab-actions'), dropdown ( btn(set::text($lang->story->create), set::target('_parent'), setClass('secondary' . (empty($createStoryLink) ? ' disabled' : '')), set::icon('plus'), set::caret(true), set::url($createStoryLink)), @@ -223,7 +223,7 @@ detailBody set::active($type == 'bug'), div ( - setClass('tabnActions'), + setClass('tab-actions'), !common::hasPriv('productplan', 'linkBug') ? null : btn(set::text($lang->productplan->linkBug), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'bug'), set('data-linkurl', inlink('linkBug', "planID={$plan->id}" . (($link == 'true' && $type == 'bug') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}"))) ), dtable diff --git a/module/release/css/view.ui.css b/module/release/css/view.ui.css index 84ff678359..8ea6d97813 100644 --- a/module/release/css/view.ui.css +++ b/module/release/css/view.ui.css @@ -1 +1 @@ -.tab-pane .tabnActions {float: right; margin-top: -48px;} +.tab-pane .tab-actions {float: right; margin-top: -48px;} diff --git a/module/release/ui/view.html.php b/module/release/ui/view.html.php index c0cda23c85..371f1461fd 100644 --- a/module/release/ui/view.html.php +++ b/module/release/ui/view.html.php @@ -142,7 +142,7 @@ detailBody set::active($type == 'story'), div ( - setClass('tabnActions'), + setClass('tab-actions'), $exportBtn, $linkStoryBtn ), @@ -169,7 +169,7 @@ detailBody set::active($type == 'bug'), div ( - setClass('tabnActions'), + setClass('tab-actions'), $exportBtn, $linkBugBtn ), @@ -195,7 +195,7 @@ detailBody set::active($type == 'leftBug'), div ( - setClass('tabnActions'), + setClass('tab-actions'), $exportBtn, $linkLeftBtn ), @@ -220,7 +220,7 @@ detailBody set::title($lang->release->basicInfo), div ( - setClass('tabnActions'), + setClass('tab-actions'), $exportBtn ), div( From de18efcbb8363e03ac0fb2c8755586d84f449bd3 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 13:12:02 +0800 Subject: [PATCH 130/235] * Change to new writing method. --- module/bug/ui/resolve.html.php | 12 ++++++------ module/testcase/ui/edit.html.php | 10 +++++----- module/testcase/ui/groupcase.html.php | 2 +- module/testcase/ui/view.html.php | 11 +++++------ module/tutorial/ui/start.html.php | 8 ++++---- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/module/bug/ui/resolve.html.php b/module/bug/ui/resolve.html.php index 6a8817d6aa..396326fd38 100644 --- a/module/bug/ui/resolve.html.php +++ b/module/bug/ui/resolve.html.php @@ -20,11 +20,11 @@ if(common::hasPriv('build', 'create')) { $createBuild = formGroup ( - set::id('createBuildBox'), + setID('createBuildBox'), set::width('1/3'), checkbox ( - set::id('createBuild'), + setID('createBuild'), set::name('createBuild'), set::rootClass('ml-4 items-center'), set::text($lang->bug->createBuild) @@ -49,7 +49,7 @@ formPanel formRow ( setClass('hidden'), - set::id('duplicateBugBox'), + setID('duplicateBugBox'), formGroup ( set::width('1/3'), @@ -66,7 +66,7 @@ formPanel formGroup ( set::width('1/3'), - set::id('newBuildExecutionBox'), + setID('newBuildExecutionBox'), setClass('hidden'), set::label(!empty($execution) && $execution->type == 'kanban' ? $lang->bug->kanban : $lang->build->execution), set::required(true), @@ -80,7 +80,7 @@ formPanel formGroup ( set::width('1/3'), - set::id('resolvedBuildBox'), + setID('resolvedBuildBox'), set::label($lang->bug->resolvedBuild), set::name('resolvedBuild'), set::value(''), @@ -90,7 +90,7 @@ formPanel ( set::width('1/3'), setClass('hidden'), - set::id('newBuildBox'), + setID('newBuildBox'), set::required(true), inputGroup ( diff --git a/module/testcase/ui/edit.html.php b/module/testcase/ui/edit.html.php index 69895dd20f..f8eaea5d3f 100644 --- a/module/testcase/ui/edit.html.php +++ b/module/testcase/ui/edit.html.php @@ -104,7 +104,7 @@ detailBody set::title($lang->testcase->scene), formGroup ( - set::id('sceneIdBox'), + setID('sceneIdBox'), picker ( set::name('scene'), @@ -184,7 +184,7 @@ detailBody ), picker ( - set::className(!isset($product->type) || $product->type == 'normal' ? 'hidden' : ''), + setClass(!isset($product->type) || $product->type == 'normal' ? 'hidden' : ''), setID('branch'), set::name('branch'), set::items($branchTagOption), @@ -199,7 +199,7 @@ detailBody ( inputGroup ( - set::id('moduleIdBox'), + setID('moduleIdBox'), picker ( setID('module'), @@ -234,7 +234,7 @@ detailBody set::name($lang->testcase->story), formGroup ( - set::id('storyIdBox'), + setID('storyIdBox'), picker ( setID('story'), @@ -259,7 +259,7 @@ detailBody ), span ( - set::className('input-group-addon'), + setClass('input-group-addon'), control ( set::type('checkbox'), diff --git a/module/testcase/ui/groupcase.html.php b/module/testcase/ui/groupcase.html.php index 3758733040..3c238ba5ec 100644 --- a/module/testcase/ui/groupcase.html.php +++ b/module/testcase/ui/groupcase.html.php @@ -30,7 +30,7 @@ $cases = initTableData(array_values($cases), $cols); dtable ( - set::id('groupCaseTable'), + setID('groupCaseTable'), set::cols($cols), set::data($cases), set::userMap($users), diff --git a/module/testcase/ui/view.html.php b/module/testcase/ui/view.html.php index a34771e542..9c8f7b875c 100644 --- a/module/testcase/ui/view.html.php +++ b/module/testcase/ui/view.html.php @@ -74,7 +74,7 @@ if($isLibCase) $linkCaseTitles[] = a ( set::href($this->createLink('testcase', 'view', "caseID={$linkCaseID}", '', true)), - set('data-toggle', 'modal'), + setData(array('toggle' => 'modal')), "#{$linkCaseID} {$linkCaseTitle}" ); } @@ -188,8 +188,7 @@ else $storyItem = item ( set::name($lang->testcase->story), - isset($case->storyTitle) && hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "storyID={$case->story}{$param}")), set('data-toggle', 'modal'), "#{$case->story}:{$case->storyTitle}") : (isset($case->storyTitle) ? "#{$case->story}:{$case->storyTitle}" : ''), - set::labelProps(array('data-toggle' => 'modal', 'data-size' => 'lg')), + isset($case->storyTitle) && hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "storyID={$case->story}{$param}")), setData(array('toggle' => 'modal')), "#{$case->story}:{$case->storyTitle}") : (isset($case->storyTitle) ? "#{$case->story}:{$case->storyTitle}" : ''), set::labelProps(array('data-toggle' => 'modal', 'data-size' => 'lg')), $confirmStatusChange ); @@ -392,7 +391,7 @@ detailBody ( $stepsType == 'table' ? div ( - set::id('stepsTable'), + setID('stepsTable'), div ( setClass('steps-header'), @@ -416,7 +415,7 @@ detailBody ) ) : div ( - set::id('stepsView'), + setID('stepsView'), mindmap ( set::data($case->mindMapSteps), @@ -448,7 +447,7 @@ detailBody floatToolbar ( set::object($case), - $isInModal ? null : to::prefix(backBtn(set::icon('back'), set::className('ghost text-white'), $lang->goback)), + $isInModal ? null : to::prefix(backBtn(set::icon('back'), setClass('ghost text-white'), $lang->goback)), set::main($actions['mainActions']), set::suffix($actions['suffixActions']) ), diff --git a/module/tutorial/ui/start.html.php b/module/tutorial/ui/start.html.php index 79ba1b2dad..1b000ab67b 100644 --- a/module/tutorial/ui/start.html.php +++ b/module/tutorial/ui/start.html.php @@ -12,18 +12,18 @@ namespace zin; div ( - set::id('start'), - set::className('bg-primary'), + setID('start'), + setClass('bg-primary'), div ( - set::className('start-icon'), + setClass('start-icon'), icon('certificate icon-certificate-empty icon1 spin'), icon('flag icon2') ), h1($lang->tutorial->common), p($lang->tutorial->desc), a( - set::className('btn btn-default btn-start-now btn-lg btn-info'), + setClass('btn btn-default btn-start-now btn-lg btn-info'), set::href($this->inlink('index')), set::target('_top'), span($lang->tutorial->start) From cacfc55619cac82b078bd8aaec1f7c709ca51f3f Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 13:23:21 +0800 Subject: [PATCH 131/235] * Fix picker not set items attribute problem. --- module/product/ui/create.html.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/product/ui/create.html.php b/module/product/ui/create.html.php index 5bdd21a77f..8ce8dbb9ee 100644 --- a/module/product/ui/create.html.php +++ b/module/product/ui/create.html.php @@ -22,7 +22,6 @@ foreach($fields as $field => $attr) $control['type'] = $attr['control']; if($attr['control'] == 'select') $control['type'] = 'picker'; if($attr['control'] == 'radio') $control['type'] = 'radioList'; - if(!empty($attr['options'])) $control['items'] = $attr['options']; if($attr['control'] == 'multi-select') { $control['type'] = 'picker'; @@ -30,6 +29,8 @@ foreach($fields as $field => $attr) $fieldName .= '[]'; } + if($control['type'] == 'picker') $control['items'] = $attr['options']; + if($field == 'line' and common::hasPriv('product', 'manageLine') and $programID) { $formGroup = formGroup From 119fb3abf254623b294e75222b368ed93f0935cd Mon Sep 17 00:00:00 2001 From: daitingting Date: Fri, 17 Nov 2023 05:30:06 +0000 Subject: [PATCH 132/235] * Check privilege. * Adjust language. --- module/product/ui/all.html.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/product/ui/all.html.php b/module/product/ui/all.html.php index 2f7eca4ed0..7a51f8d227 100644 --- a/module/product/ui/all.html.php +++ b/module/product/ui/all.html.php @@ -95,19 +95,19 @@ featureBar $canCreate = hasPriv('product', 'create'); toolbar ( - btn + hasPriv('product', 'export') ? btn ( set::className('ghost text-darker'), set::icon('export'), toggle::modal(array('url' => createLink('product', 'export', "programID=$programID&status=$browseType&orderBy=$orderBy¶m=$param"))), $lang->export - ), - in_array($this->config->systemMode, array('ALM', 'PLM')) ? btn + ) : null, + in_array($this->config->systemMode, array('ALM', 'PLM')) && hasPriv('product', 'manageline') ? btn ( set::className('ghost text-primary'), set::icon('edit'), toggle::modal(array('url' => createLink('product', 'manageLine', $browseType), 'id' => 'manageLineModal')), - $lang->product->editLine + $lang->product->line ) : null, $canCreate ? btn ( From 660f036c3eb2d18759558dd7ed0c588d59691683 Mon Sep 17 00:00:00 2001 From: tanghucheng Date: Fri, 17 Nov 2023 01:26:16 -0500 Subject: [PATCH 133/235] * Fix bug for project product. --- module/project/ui/manageproducts.html.php | 2 +- module/project/zen.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/project/ui/manageproducts.html.php b/module/project/ui/manageproducts.html.php index 3fbea0b303..ebe08c0730 100644 --- a/module/project/ui/manageproducts.html.php +++ b/module/project/ui/manageproducts.html.php @@ -17,7 +17,7 @@ jsVar('branchGroups', $branchGroups); jsVar('BRANCH_MAIN', BRANCH_MAIN); jsVar('unLinkProductTip', $lang->project->unLinkProductTip); -$noticeSwitch = (!$project->division and count($linkedProducts) == 1 and empty($executions) and in_array($project->model, array('waterfall', 'waterfallplus'))); +$noticeSwitch = ($project->stageBy == 'product' and count($linkedProducts) == 1 and empty($executions) and in_array($project->model, array('waterfall', 'waterfallplus'))); jsVar('linkedProducts', array_keys($linkedProducts)); jsVar('noticeSwitch', $noticeSwitch); jsVar('noticeDivsion', $lang->project->noticeDivsion); diff --git a/module/project/zen.php b/module/project/zen.php index cbbec79826..74c97afa3c 100644 --- a/module/project/zen.php +++ b/module/project/zen.php @@ -25,7 +25,7 @@ class projectZen extends project ->setIF($this->post->acl == 'open', 'whitelist', '') ->setIF(!isset($_POST['whitelist']), 'whitelist', '') ->setIF(!isset($_POST['multiple']), 'multiple', '1') - ->setIF($this->post->model == 'ipd', 'division', '0') + ->setIF($this->post->model == 'ipd', 'stageBy', 'project') ->setDefault('openedBy', $this->app->user->account) ->setDefault('openedDate', helper::now()) ->setDefault('team', $this->post->name) From 9301041dd3f2cafa4d2c00b7362fb3da92bac5cb Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 14:27:06 +0800 Subject: [PATCH 134/235] * Add tooltips to single product statistic block, and remove tooltip in qa statistic block and single bug statistic block. --- module/block/lang/zh-cn.php | 7 +- module/block/ui/qastatisticblock.html.php | 19 +- .../block/ui/singlebugstatisticblock.html.php | 31 ++-- module/block/ui/singlestatisticblock.html.php | 170 +++++++++--------- 4 files changed, 96 insertions(+), 131 deletions(-) diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index dee0724386..c0f153b909 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -589,7 +589,7 @@ $lang->block->projectstatistic->lastestExecution = '最新执行'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon}已关闭"; $lang->block->projectstatistic->longTimeProject = "长期{$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = '总进度'; -$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数/(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)
按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。
按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务 过滤已删除的项目。"; +$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数/(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)
按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务。
按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务。"; $lang->block->projectstatistic->currentCost = '当前成本'; $lang->block->projectstatistic->sv = '进度偏差率(SV)'; $lang->block->projectstatistic->pv = '计划完成(PV)'; @@ -710,9 +710,8 @@ $lang->block->tooltips['effectiveStory'] = '按产品统计的研发需求总 $lang->block->tooltips['deliveredStory'] = '按产品统计的已交付研发需求数:产品中研发需求个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的研发需求,过滤已删除的产品。'; $lang->block->tooltips['costs'] = '已投入=已消耗工时/每日可用工时'; $lang->block->tooltips['sv'] = '进度偏差率=(EV-PV)/PV*100% '; -$lang->block->tooltips['ev'] = "实际完成=按项目统计的任务预计工时数*按项目统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除执行下的任务,过滤已删除的项目。\n 按项目统计的任务预计工时数:项目中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务,过滤已删除的项目。"; +$lang->block->tooltips['ev'] = '实际完成=按项目统计的任务预计工时数*按项目统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除执行下的任务,过滤已删除的项目。\n 按项目统计的任务预计工时数:项目中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务,过滤已删除的项目。'; $lang->block->tooltips['pv'] = '计划完成:瀑布项目中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的执行的任务,过滤已删除的项目。'; $lang->block->tooltips['cv'] = '成本偏差率=(EV-AC)/AC*100%'; $lang->block->tooltips['ac'] = '实际花费:瀑布项目中所有日志记录的工时之和,过滤已删除的项目。'; -$lang->block->tooltips['executionProgress'] = "执行进度=按执行统计的任务消耗工时数/(按执行统计的任务消耗工时数+按执行统计的任务剩余工时数)
按执行统计的任务消耗工时数:执行中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。
按执行统计的任务剩余工时数:执行中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。"; -$lang->block->tooltips['closedBugRate'] = "Bug修复率=按产品统计的已修复Bug数/按产品统计的有效Bug数。
按产品统计的已修复Bug数:产品中Bug的个数求和,解决方案为已解决,状态为已关闭,过滤已删除的Bug,过滤已删除的产品。
按产品统计的有效Bug数:产品中所有Bug个数求和,解决方案为已解决、延期处理或状态为激活,过滤已删除的Bug,过滤已删除的产品。"; +$lang->block->tooltips['executionProgress'] = '执行进度=按执行统计的任务消耗工时数/(按执行统计的任务消耗工时数+按执行统计的任务剩余工时数)
按执行统计的任务消耗工时数:执行中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。
按执行统计的任务剩余工时数:执行中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。'; diff --git a/module/block/ui/qastatisticblock.html.php b/module/block/ui/qastatisticblock.html.php index 8bcd90f27d..97e9fbe4f9 100644 --- a/module/block/ui/qastatisticblock.html.php +++ b/module/block/ui/qastatisticblock.html.php @@ -166,23 +166,8 @@ statisticBlock div(span(setClass('text-2xl font-bold'), $product->closedBugRate), '%'), div ( - setClass('row text-sm text-gray items-center gap-1'), - $lang->block->qastatistic->closedBugRate, - icon - ( - 'help', - setClass('text-light text-sm'), - toggle::tooltip - ( - array - ( - 'content' => array('html' => $lang->block->tooltips['closedBugRate']), - 'placement' => 'bottom', - 'type' => 'white', - 'className' => 'text-dark border border-light leading-5' - ) - ) - ) + setClass('row text-gray items-center gap-1'), + $lang->block->qastatistic->closedBugRate ) ), row diff --git a/module/block/ui/singlebugstatisticblock.html.php b/module/block/ui/singlebugstatisticblock.html.php index a46d92f2dc..3cc29db592 100644 --- a/module/block/ui/singlebugstatisticblock.html.php +++ b/module/block/ui/singlebugstatisticblock.html.php @@ -28,30 +28,19 @@ panel div ( setClass('flex justify-center w-full'), - zui::progressCircle + progressCircle ( - set('percent', $resolvedRate), - set('size', 112), - set('circleWidth', 6), - set('text', $resolvedRate . '%'), - set('textY', 50), - set('textStyle', 'font-size: 30px;') - ) - ), - div - ( - setClass('flex justify-center w-full h-0'), - span - ( - setClass('text-gray text-sm progress-text'), - $lang->block->qastatistic->fixBugRate, - icon + set::percent($resolvedRate), + set::size(112), + set::text(false), + set::circleWidth(0.06), + div(span(setClass('text-2xl font-bold'), $resolvedRate), '%'), + div ( - setClass('pl-0.5'), - toggle::tooltip(array('title' => '提示文本')), - 'help' + setClass('row text-gray items-center gap-1'), + $lang->block->qastatistic->closedBugRate ) - ) + ), ), cell ( diff --git a/module/block/ui/singlestatisticblock.html.php b/module/block/ui/singlestatisticblock.html.php index d2c50a7a6f..591cc4aed2 100644 --- a/module/block/ui/singlestatisticblock.html.php +++ b/module/block/ui/singlestatisticblock.html.php @@ -50,118 +50,110 @@ panel setClass('flex h-full ' . ($longBlock ? '' : 'col')), cell ( - $longBlock ? set('width', '40%') : null, + $longBlock ? set::width('40%') : setClass('my-4'), + setClass('flex items-center'), setClass($longBlock ? 'p-4' : 'px-4'), - div + center ( - setClass('chart pie-chart ' . ($longBlock ? 'py-6' : 'py-1')), - echarts + setClass('flex-1 gap-4'), + progressCircle ( - set::color(array('#2B80FF', '#E3E4E9')), - set::series + set::percent($product->storyDeliveryRate), + set::size(112), + set::text(false), + set::circleWidth(0.06), + div(span(setClass('text-2xl font-bold'), $product->storyDeliveryRate), '%'), + div ( - array + setClass('row text-sm text-gray items-center gap-1'), + $lang->block->productstatistic->deliveryRate, + icon ( - array + setClass('text-light text-sm'), + toggle::tooltip ( - 'type' => 'pie', - 'radius' => array('80%', '90%'), - 'itemStyle' => array('borderRadius' => '40'), - 'label' => array('show' => false), - 'data' => array($product->storyDeliveryRate, 100 - $product->storyDeliveryRate) - ) + array + ( + 'title' => $lang->block->tooltips['deliveryRate'], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ), + 'help' ) ) - )->size('100%', 120), + ), div ( - set::className('pie-chart-title text-center h-0'), - div(span(set::className('text-2xl font-bold'), $product->storyDeliveryRate . '%')), - div + setClass('flex h-full story-num w-44'), + cell ( - span + setClass('flex-1 text-center'), + div ( - setClass('text-sm text-gray'), - $lang->block->productstatistic->deliveryRate, - icon + common::hasPriv('product', 'browse') && $product->totalStories ? a ( - 'help', - setClass('text-light'), - toggle::tooltip(array('title' => '提示文本')) + set('href', helper::createLink('product', 'browse', "productID={$product->id}&branch=all&browseType=allStory¶m=0&storyType=story")), + $product->totalStories + ) : span + ( + $product->totalStories + ) + ), + div + ( + span + ( + setClass('text-sm text-gray'), + $lang->block->productstatistic->effectiveStory ) ) - ) - ) - ), - div - ( - setClass('flex h-full story-num w-44'), - cell - ( - setClass('flex-1 text-center'), - div + ), + cell ( - common::hasPriv('product', 'browse') && $product->totalStories ? a + setClass('flex-1 text-center'), + div ( - set('href', helper::createLink('product', 'browse', "productID={$product->id}&branch=all&browseType=allStory¶m=0&storyType=story")), - $product->totalStories - ) : span + common::hasPriv('product', 'browse') && $product->closedStories ? a + ( + set('href', helper::createLink('product', 'browse', "productID={$product->id}&branch=all&browseType=closedstory¶m=0&storyType=story")), + $product->closedStories + ) : span + ( + $product->closedStories + ) + ), + div ( - $product->totalStories + span + ( + setClass('text-sm text-gray'), + $lang->block->productstatistic->delivered + ) ) ), - div + cell ( - span + setClass('flex-1 text-center'), + div ( - setClass('text-sm text-gray'), - $lang->block->productstatistic->effectiveStory - ) - ) - ), - cell - ( - setClass('flex-1 text-center'), - div - ( - common::hasPriv('product', 'browse') && $product->closedStories ? a + common::hasPriv('product', 'browse') && $product->unclosedStories ? a + ( + set('href', helper::createLink('product', 'browse', "productID={$product->id}&branch=all&browseType=unclosed¶m=0&storyType=story")), + $product->unclosedStories + ) : span + ( + $product->unclosedStories + ) + ), + div ( - set('href', helper::createLink('product', 'browse', "productID={$product->id}&branch=all&browseType=closedstory¶m=0&storyType=story")), - $product->closedStories - ) : span - ( - $product->closedStories - ) - ), - div - ( - span - ( - setClass('text-sm text-gray'), - $lang->block->productstatistic->delivered - ) - ) - ), - cell - ( - setClass('flex-1 text-center'), - div - ( - common::hasPriv('product', 'browse') && $product->unclosedStories ? a - ( - set('href', helper::createLink('product', 'browse', "productID={$product->id}&branch=all&browseType=unclosed¶m=0&storyType=story")), - $product->unclosedStories - ) : span - ( - $product->unclosedStories - ) - ), - div - ( - span - ( - setClass('text-sm text-gray'), - $lang->block->productstatistic->unclosed + span + ( + setClass('text-sm text-gray'), + $lang->block->productstatistic->unclosed + ) ) ) ) From f091f6557b987a31499ec8657ca700de08aa4afb Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 14:40:29 +0800 Subject: [PATCH 135/235] * Adjust copy project pop-window style when the system haven't any project. --- module/project/ui/create.html.php | 42 +++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 9233e615e8..94e6d88789 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -236,7 +236,7 @@ formPanel set::control(array('type' => 'radioList', 'inline' => true)), set::items($lang->project->multipleList), set::disabled($copyProjectID), - set::value($copyProject ? $copyProject->multiple : 1) + set::value($copyProjectID ? $copyProject->multiple : 1) ) : null, formGroup ( @@ -541,20 +541,36 @@ formPanel ); $copyProjectsBox = array(); -foreach($copyProjects as $id => $name) +if(!empty($copyProjects)) { - $copyProjectsBox[] = btn( - setClass('project-block justify-start'), - setClass($copyProjectID == $id ? 'primary-outline' : ''), - set('data-id', $id), - set('data-pinyin', zget($copyPinyinList, $name, '')), - icon + foreach($copyProjects as $id => $name) + { + $copyProjectsBox[] = btn( + setClass('project-block justify-start'), + setClass($copyProjectID == $id ? 'primary-outline' : ''), + set('data-id', $id), + set('data-pinyin', zget($copyPinyinList, $name, '')), + icon + ( + setClass('text-gray'), + $lang->icons['project'] + ), + span($name) + ); + } +} +else +{ + $copyProjectsBox[] = div ( - setClass('text-gray'), - $lang->icons['project'] - ), - span($name) - ); + setClass('inline-flex items-center w-full bg-lighter h-12 mt-2 mb-8'), + icon('exclamation-sign icon-2x pl-2 text-warning'), + span + ( + set::className('font-bold ml-2'), + $lang->project->copyNoProject + ) + ); } modalTrigger From 310a005f49e1cf208ca84706503f040400e6d2b1 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 14:42:40 +0800 Subject: [PATCH 136/235] * Change the set::className to the setClass. --- module/execution/ui/ajaxgetcopyprojectexecutions.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php index b44846b756..038e9402ca 100644 --- a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php +++ b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php @@ -17,7 +17,7 @@ if(empty($executions)) { $executionsBox[] = div ( - set::className('inline-flex items-center'), + setClass('inline-flex items-center'), setClass(empty($executions) ? 'bg-lighter h-12' : ''), icon('exclamation-sign icon-2x pl-2 text-warning'), span From 1e781f39b02b4bbe5f87895a55fd27cbba1936bb Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 17 Nov 2023 14:43:15 +0800 Subject: [PATCH 137/235] * Fix error without filter any metric. --- module/metric/ui/previewsingle.html.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/module/metric/ui/previewsingle.html.php b/module/metric/ui/previewsingle.html.php index 744b290ea5..ab99535f5c 100644 --- a/module/metric/ui/previewsingle.html.php +++ b/module/metric/ui/previewsingle.html.php @@ -10,6 +10,8 @@ declare(strict_types=1); */ namespace zin; +$currentID = $current->id ?? 0; + $fnGenerateSide = function() use($metrics, $current, $viewType, $scope, $filtersBase64) { $metricList = array(); @@ -112,9 +114,9 @@ toolbar setClass('btn text-black ghost primary-hover-500'), set::icon('exchange'), set::iconClass('icon-18'), - set::url(helper::createLink('metric', 'preview', "scope=$exchangeScope&viewType=multiple&metricID={$current->id}")), - $lang->metric->viewType->multiple - ) + set::url(helper::createLink('metric', 'preview', "scope=$exchangeScope&viewType=multiple&metricID={$currentID}")), + $lang->metric->viewType->multiple, + ), /* common::hasPriv('metric', 'preview') ? btn ( From 934b4a0a524c84a4a896b3a7e9c48842cdcd8819 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 14:51:08 +0800 Subject: [PATCH 138/235] * Change the way you determine if it is an ajax request. --- module/bug/control.php | 2 +- module/testcase/control.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index 741913b13d..7246cd09c0 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -73,7 +73,7 @@ class bug extends control $products = $this->product->getPairs($mode, 0, '', 'all'); } - if(empty($products) and substr($this->app->rawMethod, 0, 4) != 'ajax') $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=bug&objectID=$objectID")); + if(empty($products) && (helper::isAjaxRequest('zin') || helper::isAjaxRequest('fetch'))) $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=bug&objectID=$objectID")); } else { diff --git a/module/testcase/control.php b/module/testcase/control.php index c35ccb1cad..59bf44a3b7 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -62,7 +62,7 @@ class testcase extends control $mode = ($this->app->methodName == 'create' and empty($this->config->CRProduct)) ? 'noclosed' : ''; $products = $this->product->getPairs($mode, 0, '', 'all'); } - if(empty($products) and substr($this->app->rawMethod, 0, 4) != 'ajax') $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=testcase&objectID=$objectID")); + if(empty($products) && (helper::isAjaxRequest('zin') || helper::isAjaxRequest('fetch'))) $this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=testcase&objectID=$objectID")); } else { From 788a33c011206ce4e3b40d1d4930672b66c33b8e Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 17 Nov 2023 14:56:28 +0800 Subject: [PATCH 139/235] * project: replace $.state.value with $.value and replace $.changeState with $.setValue. --- module/project/js/common.ui.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index d591389ddd..1bcb0b692c 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -84,8 +84,8 @@ function computeDaysDelta(date1, date2) */ function computeWorkDays() { - const begin = $('#begin').zui('datePicker').$.state.value; - const end = $('#end').zui('datePicker').$.state.value; + const begin = $('#begin').zui('datePicker').$.value; + const end = $('#end').zui('datePicker').$.value; if(end == LONG_TIME) { @@ -116,7 +116,7 @@ function computeWorkDays() */ function computeEndDate() { - const beginDate = $('#begin').zui('datePicker').$.state.value; + const beginDate = $('#begin').zui('datePicker').$.value; if(!beginDate) return; const delta = parseInt($('input[name=delta]:checked').val()); @@ -125,7 +125,7 @@ function computeEndDate() const isLongTime = delta == 999; const endDate = isLongTime ? LONG_TIME : formatDate(beginDate, delta - 1); - $('#end').toggleClass('hidden', isLongTime).zui('datePicker').$.changeState({value: endDate}); + $('#end').toggleClass('hidden', isLongTime).zui('datePicker').$.setValue(endDate); $('#end').next().toggleClass('hidden', !isLongTime); $('#days').closest('.form-row').toggleClass('hidden', isLongTime); } From 2ce0e28a0208c5684d076c55a5ec950f631f6361 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 14:32:26 +0800 Subject: [PATCH 140/235] * Change to new writing method. --- module/testcase/ui/browse.html.php | 2 +- module/testcase/ui/create.html.php | 60 +++++++++++++------------ module/testcase/ui/createscene.html.php | 12 ++--- module/testcase/ui/editscene.html.php | 16 +++---- module/testcase/ui/zerocase.html.php | 8 ++-- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/module/testcase/ui/browse.html.php b/module/testcase/ui/browse.html.php index 882081d4c0..3ffe56053d 100644 --- a/module/testcase/ui/browse.html.php +++ b/module/testcase/ui/browse.html.php @@ -149,7 +149,7 @@ dtable modal ( on::click('button[type="submit"]', 'getCheckedCaseIdList'), - set::id('importToLib'), + setID('importToLib'), set::modalProps(array('title' => $lang->testcase->importToLib)), formPanel ( diff --git a/module/testcase/ui/create.html.php b/module/testcase/ui/create.html.php index d383d57eb2..b35b78f203 100644 --- a/module/testcase/ui/create.html.php +++ b/module/testcase/ui/create.html.php @@ -43,16 +43,16 @@ formPanel ( picker ( - set::id('product'), + setID('product'), set::name('product'), set::items($products), set::value(!empty($case->product) ? $case->product : $productID) ), picker ( - set::className(!isset($product->type) || $product->type == 'normal' ? 'hidden' : ''), + setID('branch'), + setClass(!isset($product->type) || $product->type == 'normal' ? 'hidden' : ''), set::width('100px'), - set::id('branch'), set::name('branch'), set::items($branches), set::value($branch), @@ -67,10 +67,10 @@ formPanel set::required(strpos(",{$config->testcase->create->requiredFields},", ',module,') !== false), inputGroup ( - set('id', 'moduleBox'), + setID('moduleBox'), picker ( - set::id('module'), + setID('module'), set::name('module'), set::items($moduleOptionMenu), set::value($currentModuleID), @@ -78,19 +78,24 @@ formPanel ), span ( - set('class', 'input-group-addon' . (count($moduleOptionMenu) > 1 ? ' hidden' : '')), + setClass('input-group-addon' . (count($moduleOptionMenu) > 1 ? ' hidden' : '')), a ( - set('class', 'mr-2'), + setClass('mr-2'), set('href', $this->createLink('tree', 'browse', "rootID=$productID&view=case¤tModuleID=0&branch={$branch}")), - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setData + ( + array( + 'toggle' => 'modal', + 'size' => 'lg' + ) + ), $lang->tree->manage ), a ( - set('id', 'refreshModule'), - set('class', 'text-black'), + setID('refreshModule'), + setClass('text-black'), set('href', 'javascript:void(0)'), icon('refresh') ) @@ -106,10 +111,10 @@ formPanel set::label($lang->testcase->scene), inputGroup ( - set('id', 'sceneBox'), + setID('sceneBox'), picker ( - set::id('scene'), + setID('scene'), set::name('scene'), set::items($sceneOptionMenu), set::value($currentSceneID), @@ -127,7 +132,7 @@ formPanel set::required(strpos(",{$config->testcase->create->requiredFields},", ',type,') !== false), picker ( - set::id('type'), + setID('type'), set::name('type'), set::items($lang->testcase->typeList), set::value($case->type), @@ -139,7 +144,7 @@ formPanel setClass('ml-2 items-center'), checkbox ( - set::id('auto'), + setID('auto'), set::name('auto'), set::value('auto'), set::text($lang->testcase->automated) @@ -175,10 +180,10 @@ formPanel set::required(strpos(",{$config->testcase->create->requiredFields},", ',stage,') !== false), inputGroup ( - set('id', 'stageBox'), + setID('stageBox'), picker ( - set::id('stage'), + setID('stage'), set::name('stage[]'), set::multiple(true), set::items($lang->testcase->stageList), @@ -196,23 +201,22 @@ formPanel set::required(strpos(",{$config->testcase->create->requiredFields},", ',story,') !== false), inputGroup ( - set('id', 'storyBox'), + setID('storyBox'), picker ( - set::id('story'), + setID('story'), set::name('story'), set::items($stories), set::value($case->story) ), span ( - set('class', 'input-group-addon'), - set('class' , !$case->story ? 'hidden' : ''), + setClass('input-group-addon' . (!$case->story ? ' hidden' : '')), a ( - set::id('preview'), + setID('preview'), set::href(helper::createLink('story', 'view', "storyID={$case->story}")), - set('data-toggle', 'modal'), + setData(array('toggle' => 'modal')), $lang->preview ) ) @@ -267,7 +271,7 @@ formPanel ( width('80px'), set::items($lang->testcase->reviewList), - set::id('needReview'), + setID('needReview'), set::name('needReview'), set::value('0'), set::required(true) @@ -322,7 +326,7 @@ function printStepsTable() { $stepsTR[] = h::tr ( - h::td(set::className('center'), $i), + h::td(setClass('center'), $i), h::td ( inputGroup @@ -334,7 +338,7 @@ function printStepsTable() ), span ( - set('class', 'input-group-addon'), + setClass('input-group-addon'), checkbox ( set::name("stepType[$i]"), @@ -353,7 +357,7 @@ function printStepsTable() ), h::td ( - set::className('center'), + setClass('center'), btnGroup ( set::items(array( @@ -367,7 +371,7 @@ function printStepsTable() } return h::table ( - set::className('w-full'), + setClass('w-full'), h::thead ( h::tr diff --git a/module/testcase/ui/createscene.html.php b/module/testcase/ui/createscene.html.php index 6d06c0e6ce..e6f6d33ce3 100644 --- a/module/testcase/ui/createscene.html.php +++ b/module/testcase/ui/createscene.html.php @@ -51,7 +51,7 @@ formPanel inputGroup ( $lang->testcase->module, - set::id('moduleIdBox'), + setID('moduleIdBox'), picker ( setID('module'), @@ -61,19 +61,19 @@ formPanel ), count($modules) == 1 ? div ( - set::className('input-group-btn flex'), + setClass('input-group-btn flex'), a ( $lang->tree->manage, set('href', createLink('tree', 'browse', "rootId=$productID&view=case¤tModuleID=0&branch=$branch")), - set('class', 'btn'), - set('data-toggle', 'mdoal') + setClass('btn'), + setData(array('toggle', 'mdoal')) ), a ( $lang->refresh, set('href', 'javascript:;'), - set('class', 'btn refresh') + setClass('btn refresh') ) ) : null ) @@ -82,7 +82,7 @@ formPanel formGroup ( set::label($lang->testcase->parentScene), - set::id('sceneIdBox'), + setID('sceneIdBox'), picker ( setID('parent'), diff --git a/module/testcase/ui/editscene.html.php b/module/testcase/ui/editscene.html.php index 044bb20730..16f3985e43 100644 --- a/module/testcase/ui/editscene.html.php +++ b/module/testcase/ui/editscene.html.php @@ -60,7 +60,7 @@ formPanel inputGroup ( $lang->testcase->module, - set::id('moduleIdBox'), + setID('moduleIdBox'), picker ( setID('module'), @@ -71,19 +71,19 @@ formPanel ), count($modules) == 1 ? div ( - set::className('input-group-btn flex'), + setClass('input-group-btn flex'), a ( - $lang->tree->manage, + setClass('btn'), + setData(array('toggle' => 'mdoal')), set('href', createLink('tree', 'browse', "rootId=$productID&view=case¤tModuleID=0&branch=$branch")), - set('class', 'btn'), - set('data-toggle', 'mdoal') + $lang->tree->manage ), a ( + setClass('btn refresh'), $lang->refresh, - set('href', 'javascript:;'), - set('class', 'btn refresh') + set('href', 'javascript:;') ) ) : null ) @@ -92,7 +92,7 @@ formPanel formGroup ( set::label($lang->testcase->parentScene), - set::id('sceneIdBox'), + setID('sceneIdBox'), picker ( set::name('parent'), diff --git a/module/testcase/ui/zerocase.html.php b/module/testcase/ui/zerocase.html.php index f808b5c280..cb9ceed34d 100644 --- a/module/testcase/ui/zerocase.html.php +++ b/module/testcase/ui/zerocase.html.php @@ -44,8 +44,8 @@ foreach($lang->story->reviewResultList as $key => $result) menu ( - set::id('navReview'), - set::className('dropdown-menu'), + setID('navReview'), + setClass('dropdown-menu'), set::items($reviewItems) ); @@ -55,8 +55,8 @@ foreach($lang->story->stageList as $key => $stage) $stageItems[] = array('text' menu ( - set::id('navStage'), - set::className('dropdown-menu'), + setID('navStage'), + setClass('dropdown-menu'), set::items($stageItems) ); From d9ff6e5656490274e9f4fd0aba8d29101d8ec076 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 15:30:44 +0800 Subject: [PATCH 141/235] * Change to new writing method. --- module/custom/ui/code.html.php | 2 +- module/custom/ui/timezone.html.php | 2 +- module/testcase/ui/automation.html.php | 12 ++++++------ module/todo/ui/batchcreate.html.php | 2 +- module/todo/ui/create.html.php | 22 +++++++++++----------- module/todo/ui/view.html.php | 20 +++++++++++++------- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/module/custom/ui/code.html.php b/module/custom/ui/code.html.php index 273a2caea2..6a0955e0d6 100644 --- a/module/custom/ui/code.html.php +++ b/module/custom/ui/code.html.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace zin; formPanel ( - set::id('setCodeForm'), + setID('setCodeForm'), set::actions(array('submit')), formRow ( diff --git a/module/custom/ui/timezone.html.php b/module/custom/ui/timezone.html.php index 38fe6e5003..7dac32eb99 100644 --- a/module/custom/ui/timezone.html.php +++ b/module/custom/ui/timezone.html.php @@ -26,7 +26,7 @@ else include $this->app->getConfigRoot() . 'timezones.php'; formPanel ( - set::id('timezoneForm'), + setID('timezoneForm'), set::actions(array('submit')), set::actionsClass('w-1/3'), formRow diff --git a/module/testcase/ui/automation.html.php b/module/testcase/ui/automation.html.php index 5a8d117c15..45787c9c8d 100644 --- a/module/testcase/ui/automation.html.php +++ b/module/testcase/ui/automation.html.php @@ -17,14 +17,14 @@ to::header span ( $lang->testcase->automation, - set::className('article-h1') + setClass('article-h1') ), icon ( 'help', - set::className('text-gray'), - set::id('automationTip'), - set('data-toggle', 'tooltip'), + setClass('text-gray'), + setID('automationTip'), + setData(array('toggle' => 'tooltip')), set('title', 'tooltip') ) ); @@ -57,10 +57,10 @@ formPanel ), div ( - set::className('input-group-btn'), + setClass('input-group-btn'), a ( - set::className('btn'), + setClass('btn'), $lang->zanode->create, set::href(createLink('zanode', 'create')), set::target('_blank') diff --git a/module/todo/ui/batchcreate.html.php b/module/todo/ui/batchcreate.html.php index 7629e3336c..ecdde54557 100644 --- a/module/todo/ui/batchcreate.html.php +++ b/module/todo/ui/batchcreate.html.php @@ -34,7 +34,7 @@ div formBatchPanel ( - set::id('batchCreateTodoForm'), + setID('batchCreateTodoForm'), set::customFields(array('list' => $customFields, 'show' => explode(',', $showFields), 'key' => 'batchCreateFields')), on::change('[data-name="type"]', 'changeType'), diff --git a/module/todo/ui/create.html.php b/module/todo/ui/create.html.php index d45a2885f4..2aaed14516 100644 --- a/module/todo/ui/create.html.php +++ b/module/todo/ui/create.html.php @@ -59,9 +59,9 @@ formPanel set::seg(true), control ( - set::id('date'), + setID('date'), + setClass('date'), set::name('date'), - set::className('date'), set::value('today'), set::type('datePicker'), on::change('changeCreateDate') @@ -70,10 +70,10 @@ formPanel setClass('input-group-addon'), checkbox ( - set::id('switchDate'), + setID('switchDate'), + setClass($lang->todo->periods['future']), set::name('switchDate'), set::text($lang->todo->periods['future']), - set::className($lang->todo->periods['future']), on::change("zui.DatePicker.query('#date').render({disabled: e.target.checked})") ) ), @@ -81,7 +81,7 @@ formPanel setClass('input-group-addon'), checkbox ( - set::id('cycle'), + setID('cycle'), set::name('cycle'), set::value('1'), set::text($lang->todo->cycle), @@ -132,10 +132,10 @@ formPanel ), control ( + setID('configDate'), set::type('datePicker'), - set::id('configDate'), set::name('config[date]'), - set::className('cycle-date'), + setClass('cycle-date'), on::change("e.target.closest('.input-group').classList.toggle('has-error', !e.target.value)") ) ) @@ -353,8 +353,8 @@ formPanel setClass('items-center ml-4'), checkbox ( + setID('private'), set::name('private'), - set::id('private'), set::text($lang->todo->private), set::value(1), on::change("zui.Picker.query('#assignedTo').render({disabled: e.target.checked})") @@ -364,7 +364,7 @@ formPanel set::icon('help'), toggle::tooltip(array('placement' => 'top-start', 'title' => $lang->todo->privateTip)), set::square(true), - set::className('ghost h-6 mt-0.5 tooltip-btn') + setClass('ghost h-6 mt-0.5 tooltip-btn') ) ) ), @@ -376,8 +376,8 @@ formPanel set(array('id' => 'nameBox', 'required' => true, 'label' => $lang->todo->name, 'class' => 'name-box')), div ( - setClass('w-full'), setID('nameInputBox'), + setClass('w-full'), input(set(array('id' => 'name', 'name' => 'name'))) ) ), @@ -402,9 +402,9 @@ formPanel ), formGroup ( + setID('status'), set::width('1/3'), set::label($lang->todo->status), - set::id('status'), set::name('status'), set::items($lang->todo->statusList), set::required(true) diff --git a/module/todo/ui/view.html.php b/module/todo/ui/view.html.php index cd27e94653..bfeb5d9387 100644 --- a/module/todo/ui/view.html.php +++ b/module/todo/ui/view.html.php @@ -120,8 +120,8 @@ if(hasPriv('task', 'create')) ( div ( - set::className('toolbar gap-4 w-full justify-center'), - btn($lang->todo->reasonList['task'], set::id('toTaskButton'), setClass('primary')), + setClass('toolbar gap-4 w-full justify-center'), + btn($lang->todo->reasonList['task'], setID('toTaskButton'), setClass('primary')), on::click('toTask') ) ), @@ -165,8 +165,8 @@ if(hasPriv('bug', 'create')) ( div ( - set::className('toolbar gap-4 w-full justify-center'), - btn($lang->todo->reasonList['bug'], set::id('toBugButton'), setClass('primary')), + setClass('toolbar gap-4 w-full justify-center'), + btn($lang->todo->reasonList['bug'], setID('toBugButton'), setClass('primary')), on::click('toBug') ) ), @@ -318,9 +318,15 @@ $fnGenerateFrom = function() use ($app, $lang, $config, $todo) a ( set::href(createLink($todo->type, 'view', "id={$todo->objectID}", '', false)), - set('data-toggle', 'modal'), - set('data-data-type', 'html'), - set('data-type', 'ajax'), + setData + ( + array + ( + 'toggle' => 'modal', + 'data-type' => 'html', + 'type' => 'ajax' + ) + ), $todo->name ) ); From 3cb3f3b07d49f872fce10c2a5193c8eac61128a3 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 15:39:46 +0800 Subject: [PATCH 142/235] * Add other language item for the tooltips in block, and use html for ev tooltip in project statistic block. --- module/block/lang/de.php | 19 ++++++++++++- module/block/lang/en.php | 19 ++++++++++++- module/block/lang/fr.php | 19 ++++++++++++- module/block/lang/zh-cn.php | 27 +++++++++++-------- .../block/ui/projectstatisticblock.html.php | 4 +-- 5 files changed, 72 insertions(+), 16 deletions(-) diff --git a/module/block/lang/de.php b/module/block/lang/de.php index 0cf0de76d5..8b5e49f8a8 100644 --- a/module/block/lang/de.php +++ b/module/block/lang/de.php @@ -598,7 +598,9 @@ $lang->block->projectstatistic->lastestExecution = 'Lastest Execution'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon} has been closed."; $lang->block->projectstatistic->longTimeProject = "Long Time {$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = 'Total Progress'; -$lang->block->projectstatistic->totalProgressTip = 'Total Progress = Consumed Man Hours/(Consumed Man Hours + Left Man Hours)'; +$lang->block->projectstatistic->totalProgressTip = "Total Progress = Number of hours spent on tasks by {$lang->projectCommon}/(Number of hours spent on tasks by {$lang->projectCommon} + Number of hours remaining on tasks by {$lang->projectCommon})
+Number of hours consumed on tasks by {$lang->projectCommon}: Summarise the number of hours spent on tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}.
+Number of hours remaining on tasks by {$lang->projectCommon}: Summarise the remaining hours of tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}."; $lang->block->projectstatistic->currentCost = 'Current Cost'; $lang->block->projectstatistic->sv = 'Schedule Variance(SV)'; $lang->block->projectstatistic->pv = 'Planned Value(PV)'; @@ -712,3 +714,18 @@ $lang->block->moduleList['teamachievement'] = $lang->block->teamAchievement; $lang->block->moduleList['assigntome'] = $lang->block->assignToMe; $lang->block->moduleList['dynamic'] = $lang->block->dynamic; $lang->block->moduleList['html'] = $lang->block->html; + +$lang->block->tooltips = array(); +$lang->block->tooltips['deliveryRate'] = "{$lang->SRCommon} delivery rate = Number of {$lang->SRCommon} delivered by {$lang->productCommon} / (Total number of {$lang->SRCommon} by {$lang->productCommon} - Number of {$lang->SRCommon} delivered by {$lang->productCommon}) * 100%"; +$lang->block->tooltips['effectiveStory'] = "Total number of {$lang->SRCommon} by {$lang->productCommon}: Sum the number of {$lang->SRCommon} in a {$lang->productCommon}, filter deleted {$lang->SRCommon} and filter deleted {$lang->productCommon}."; +$lang->block->tooltips['deliveredStory'] = "Number of {$lang->SRCommon} delivered by {$lang->productCommon}: Sum the number of {$lang->SRCommon} in the {$lang->productCommon}, the stage is released or the reason for closure is done, filter the deleted {$lang->SRCommon} and filter the deleted {$lang->productCommon}."; +$lang->block->tooltips['costs'] = "Have invested = Hours consumed / Available hours per day"; +$lang->block->tooltips['sv'] = "Schedule Variance = (EV - PV) / PV * 100% "; +$lang->block->tooltips['ev'] = "Earned Value = Number of estimated hours worked on tasks by {$lang->projectCommon} * Progress of tasks by {$lang->projectCommon}, filter deleted tasks, filter cancelled tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}.
+Number of estimated hours worked on tasks by {$lang->projectCommon}: Summarise the estimated hours of tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}."; +$lang->block->tooltips['pv'] = "Planned Value: Summarise the estimated hours for all tasks in the waterfall {$lang->projectCommon}, filter deleted tasks, filter cancelled tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}."; +$lang->block->tooltips['cv'] = 'Cost Variance = (EV - AC) / AC * 100%'; +$lang->block->tooltips['ac'] = "Actual Cost: Summarise all logged hours in the waterfall {$lang->projectCommon}, filtering for deleted {$lang->projectCommon}."; +$lang->block->tooltips['executionProgress'] = "Total Progress = Number of hours consumed for task by {$lang->execution->common}/(Number of hours consumed for tasks by {$lang->execution->common} + Number of hours remaining for tasks by {$lang->execution->common})
+Number of hours consumed for tasks by {$lang->execution->common}: Summarise the number of hours consumed for tasks by {$lang->execution->common}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}, filter tasks in deleted {$lang->projectCommon}.
+Number of hours remaining for tasks by {$lang->execution->common}: Summarise the number of remaining hours for tasks by {$lang->execution->common}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}, filter tasks in deleted {$lang->projectCommon}."; diff --git a/module/block/lang/en.php b/module/block/lang/en.php index 307966a7ed..85149081e6 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -598,7 +598,9 @@ $lang->block->projectstatistic->lastestExecution = 'Lastest Execution'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon} has been closed."; $lang->block->projectstatistic->longTimeProject = "Long Time {$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = 'Total Progress'; -$lang->block->projectstatistic->totalProgressTip = 'Total Progress = Consumed Man Hours/(Consumed Man Hours + Left Man Hours)'; +$lang->block->projectstatistic->totalProgressTip = "Total Progress = Number of hours spent on tasks by {$lang->projectCommon}/(Number of hours spent on tasks by {$lang->projectCommon} + Number of hours remaining on tasks by {$lang->projectCommon})
+Number of hours consumed on tasks by {$lang->projectCommon}: Summarise the number of hours spent on tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}.
+Number of hours remaining on tasks by {$lang->projectCommon}: Summarise the remaining hours of tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}."; $lang->block->projectstatistic->currentCost = 'Current Cost'; $lang->block->projectstatistic->sv = 'Schedule Variance(SV)'; $lang->block->projectstatistic->pv = 'Planned Value(PV)'; @@ -712,3 +714,18 @@ $lang->block->moduleList['teamachievement'] = $lang->block->teamAchievement; $lang->block->moduleList['assigntome'] = $lang->block->assignToMe; $lang->block->moduleList['dynamic'] = $lang->block->dynamic; $lang->block->moduleList['html'] = $lang->block->html; + +$lang->block->tooltips = array(); +$lang->block->tooltips['deliveryRate'] = "{$lang->SRCommon} delivery rate = Number of {$lang->SRCommon} delivered by {$lang->productCommon} / (Total number of {$lang->SRCommon} by {$lang->productCommon} - Number of {$lang->SRCommon} delivered by {$lang->productCommon}) * 100%"; +$lang->block->tooltips['effectiveStory'] = "Total number of {$lang->SRCommon} by {$lang->productCommon}: Sum the number of {$lang->SRCommon} in a {$lang->productCommon}, filter deleted {$lang->SRCommon} and filter {$lang->SRCommon} in deleted {$lang->productCommon}."; +$lang->block->tooltips['deliveredStory'] = "Number of {$lang->SRCommon} delivered by {$lang->productCommon}: Sum the number of {$lang->SRCommon} in the {$lang->productCommon}, the stage is released or the reason for closure is done, filter the deleted {$lang->SRCommon} and filter the {$lang->SRCommon} in deleteddeleted {$lang->productCommon}."; +$lang->block->tooltips['costs'] = "Have invested = Hours consumed / Available hours per day"; +$lang->block->tooltips['sv'] = "Schedule Variance = (EV - PV) / PV * 100% "; +$lang->block->tooltips['ev'] = "Earned Value = Number of estimated hours worked on tasks by {$lang->projectCommon} * Progress of tasks by {$lang->projectCommon}, filter deleted tasks, filter cancelled tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}.
+Number of estimated hours worked on tasks by {$lang->projectCommon}: Summarise the estimated hours of tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}."; +$lang->block->tooltips['pv'] = "Planned Value: Summarise the estimated hours for all tasks in the waterfall {$lang->projectCommon}, filter deleted tasks, filter cancelled tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}."; +$lang->block->tooltips['cv'] = 'Cost Variance = (EV - AC) / AC * 100%'; +$lang->block->tooltips['ac'] = "Actual Cost: Summarise all logged hours in the waterfall {$lang->projectCommon}, filtering for deleted {$lang->projectCommon}."; +$lang->block->tooltips['executionProgress'] = "Total Progress = Number of hours consumed for task by {$lang->execution->common}/(Number of hours consumed for tasks by {$lang->execution->common} + Number of hours remaining for tasks by {$lang->execution->common})
+Number of hours consumed for tasks by {$lang->execution->common}: Summarise the number of hours consumed for tasks by {$lang->execution->common}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}, filter tasks in deleted {$lang->projectCommon}.
+Number of hours remaining for tasks by {$lang->execution->common}: Summarise the number of remaining hours for tasks by {$lang->execution->common}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}, filter tasks in deleted {$lang->projectCommon}."; diff --git a/module/block/lang/fr.php b/module/block/lang/fr.php index 34a638b5b3..299a288068 100644 --- a/module/block/lang/fr.php +++ b/module/block/lang/fr.php @@ -591,7 +591,9 @@ $lang->block->projectstatistic->lastestExecution = 'Lastest Execution'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon} has been closed."; $lang->block->projectstatistic->longTimeProject = "Long Time {$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = 'Total Progress'; -$lang->block->projectstatistic->totalProgressTip = 'Total Progress = Consumed Man Hours/(Consumed Man Hours + Left Man Hours)'; +$lang->block->projectstatistic->totalProgressTip = "Total Progress = Number of hours spent on tasks by {$lang->projectCommon}/(Number of hours spent on tasks by {$lang->projectCommon} + Number of hours remaining on tasks by {$lang->projectCommon})
+Number of hours consumed on tasks by {$lang->projectCommon}: Summarise the number of hours spent on tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}.
+Number of hours remaining on tasks by {$lang->projectCommon}: Summarise the remaining hours of tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}."; $lang->block->projectstatistic->currentCost = 'Current Cost'; $lang->block->projectstatistic->sv = 'Schedule Variance(SV)'; $lang->block->projectstatistic->pv = 'Planned Value(PV)'; @@ -705,3 +707,18 @@ $lang->block->moduleList['teamachievement'] = $lang->block->teamAchievement; $lang->block->moduleList['assigntome'] = $lang->block->assignToMe; $lang->block->moduleList['dynamic'] = $lang->block->dynamic; $lang->block->moduleList['html'] = $lang->block->html; + +$lang->block->tooltips = array(); +$lang->block->tooltips['deliveryRate'] = "{$lang->SRCommon} delivery rate = Number of {$lang->SRCommon} delivered by {$lang->productCommon} / (Total number of {$lang->SRCommon} by {$lang->productCommon} - Number of {$lang->SRCommon} delivered by {$lang->productCommon}) * 100%"; +$lang->block->tooltips['effectiveStory'] = "Total number of {$lang->SRCommon} by {$lang->productCommon}: Sum the number of {$lang->SRCommon} in a {$lang->productCommon}, filter deleted {$lang->SRCommon} and filter deleted {$lang->productCommon}."; +$lang->block->tooltips['deliveredStory'] = "Number of {$lang->SRCommon} delivered by {$lang->productCommon}: Sum the number of {$lang->SRCommon} in the {$lang->productCommon}, the stage is released or the reason for closure is done, filter the deleted {$lang->SRCommon} and filter the deleted {$lang->productCommon}."; +$lang->block->tooltips['costs'] = "Have invested = Hours consumed / Available hours per day"; +$lang->block->tooltips['sv'] = "Schedule Variance = (EV - PV) / PV * 100% "; +$lang->block->tooltips['ev'] = "Earned Value = Number of estimated hours worked on tasks by {$lang->projectCommon} * Progress of tasks by {$lang->projectCommon}, filter deleted tasks, filter cancelled tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}.
+Number of estimated hours worked on tasks by {$lang->projectCommon}: Summarise the estimated hours of tasks in a {$lang->projectCommon}, filter deleted tasks, filter parent tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}."; +$lang->block->tooltips['pv'] = "Planned Value: Summarise the estimated hours for all tasks in the waterfall {$lang->projectCommon}, filter deleted tasks, filter cancelled tasks, filter tasks in deleted tasks, filter tasks in deleted {$lang->projectCommon}."; +$lang->block->tooltips['cv'] = 'Cost Variance = (EV - AC) / AC * 100%'; +$lang->block->tooltips['ac'] = "Actual Cost: Summarise all logged hours in the waterfall {$lang->projectCommon}, filtering for deleted {$lang->projectCommon}."; +$lang->block->tooltips['executionProgress'] = "Total Progress = Number of hours consumed for task by {$lang->execution->common}/(Number of hours consumed for tasks by {$lang->execution->common} + Number of hours remaining for tasks by {$lang->execution->common})
+Number of hours consumed for tasks by {$lang->execution->common}: Summarise the number of hours consumed for tasks by {$lang->execution->common}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}, filter tasks in deleted {$lang->projectCommon}.
+Number of hours remaining for tasks by {$lang->execution->common}: Summarise the number of remaining hours for tasks by {$lang->execution->common}, filter deleted tasks, filter parent tasks, filter tasks in deleted {$lang->execution->common}, filter tasks in deleted {$lang->projectCommon}."; diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index c0f153b909..1c12cc3467 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -589,7 +589,9 @@ $lang->block->projectstatistic->lastestExecution = '最新执行'; $lang->block->projectstatistic->projectClosed = "{$lang->projectCommon}已关闭"; $lang->block->projectstatistic->longTimeProject = "长期{$lang->projectCommon}"; $lang->block->projectstatistic->totalProgress = '总进度'; -$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数/(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)
按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务。
按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务。"; +$lang->block->projectstatistic->totalProgressTip = "项目总进度=按项目统计的任务消耗工时数 /(按项目统计的任务消耗工时数+按项目统计的任务剩余工时数)
+按项目统计的任务消耗工时数:项目中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务。
+按项目统计的任务剩余工时数:项目中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务。"; $lang->block->projectstatistic->currentCost = '当前成本'; $lang->block->projectstatistic->sv = '进度偏差率(SV)'; $lang->block->projectstatistic->pv = '计划完成(PV)'; @@ -705,13 +707,16 @@ $lang->block->moduleList['dynamic'] = $lang->block->dynamic; $lang->block->moduleList['html'] = $lang->block->html; $lang->block->tooltips = array(); -$lang->block->tooltips['deliveryRate'] = '需求交付率=按产品统计的已交付研发需求数/(按产品统计的研发需求总数-按产品统计的无效研发需求数)*100%'; -$lang->block->tooltips['effectiveStory'] = '按产品统计的研发需求总数:产品中研发需求的个数求和,过滤已删除的研发需求,过滤已删除的产品。'; -$lang->block->tooltips['deliveredStory'] = '按产品统计的已交付研发需求数:产品中研发需求个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的研发需求,过滤已删除的产品。'; -$lang->block->tooltips['costs'] = '已投入=已消耗工时/每日可用工时'; -$lang->block->tooltips['sv'] = '进度偏差率=(EV-PV)/PV*100% '; -$lang->block->tooltips['ev'] = '实际完成=按项目统计的任务预计工时数*按项目统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除执行下的任务,过滤已删除的项目。\n 按项目统计的任务预计工时数:项目中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除执行的任务,过滤已删除的项目。'; -$lang->block->tooltips['pv'] = '计划完成:瀑布项目中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的执行的任务,过滤已删除的项目。'; -$lang->block->tooltips['cv'] = '成本偏差率=(EV-AC)/AC*100%'; -$lang->block->tooltips['ac'] = '实际花费:瀑布项目中所有日志记录的工时之和,过滤已删除的项目。'; -$lang->block->tooltips['executionProgress'] = '执行进度=按执行统计的任务消耗工时数/(按执行统计的任务消耗工时数+按执行统计的任务剩余工时数)
按执行统计的任务消耗工时数:执行中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。
按执行统计的任务剩余工时数:执行中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的执行,过滤已删除的项目。'; +$lang->block->tooltips['deliveryRate'] = "{$lang->SRCommon}交付率=按{$lang->productCommon}统计的已交付{$lang->SRCommon}数 /(按{$lang->productCommon}统计的{$lang->SRCommon}总数 - 按{$lang->productCommon}统计的无效{$lang->SRCommon}数) * 100%"; +$lang->block->tooltips['effectiveStory'] = "按{$lang->productCommon}统计的{$lang->SRCommon}总数:{$lang->productCommon}中{$lang->SRCommon}的个数求和,过滤已删除的{$lang->SRCommon},过滤已删除的{$lang->productCommon}。"; +$lang->block->tooltips['deliveredStory'] = "按{$lang->productCommon}统计的已交付{$lang->SRCommon}数:{$lang->productCommon}中{$lang->SRCommon}个数求和,所处阶段为已发布或关闭原因为已完成,过滤已删除的{$lang->SRCommon},过滤已删除的{$lang->productCommon}。"; +$lang->block->tooltips['costs'] = "已投入 = 已消耗工时 / 每日可用工时"; +$lang->block->tooltips['sv'] = "进度偏差率 = (EV - PV) / PV * 100% "; +$lang->block->tooltips['ev'] = "实际完成=按{$lang->projectCommon}统计的任务预计工时数*按{$lang->projectCommon}统计的任务进度,过滤已删除的任务,过滤已取消的任务,过滤已删除{$lang->execution->common}下的任务,过滤已删除的{$lang->projectCommon}。
+按{$lang->projectCommon}统计的任务预计工时数:{$lang->projectCommon}中任务的预计工时数求和,过滤已删除的任务,过滤父任务,过滤已删除{$lang->execution->common}的任务,过滤已删除的{$lang->projectCommon}。"; +$lang->block->tooltips['pv'] = "计划完成:瀑布{$lang->projectCommon}中所有任务的预计工时之和,过滤已删除的任务,过滤已取消的任务,过滤已删除的{$lang->execution->common}的任务,过滤已删除的{$lang->projectCommon}。"; +$lang->block->tooltips['cv'] = "成本偏差率 = (EV - AC) / AC * 100%"; +$lang->block->tooltips['ac'] = "实际花费:瀑布{$lang->projectCommon}中所有日志记录的工时之和,过滤已删除的{$lang->projectCommon}。"; +$lang->block->tooltips['executionProgress'] = "{$lang->execution->common}进度=按{$lang->execution->common}统计的任务消耗工时数 /(按{$lang->execution->common}统计的任务消耗工时数+按{$lang->execution->common}统计的任务剩余工时数)
+按{$lang->execution->common}统计的任务消耗工时数:{$lang->execution->common}中任务的消耗工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的{$lang->execution->common},过滤已删除的{$lang->projectCommon}。
+按{$lang->execution->common}统计的任务剩余工时数:{$lang->execution->common}中任务的剩余工时数求和,过滤已删除的任务,过滤父任务,过滤已删除的{$lang->execution->common},过滤已删除的{$lang->projectCommon}。"; diff --git a/module/block/ui/projectstatisticblock.html.php b/module/block/ui/projectstatisticblock.html.php index 6e3c6e402d..5ac4584911 100644 --- a/module/block/ui/projectstatisticblock.html.php +++ b/module/block/ui/projectstatisticblock.html.php @@ -290,7 +290,7 @@ else ( array ( - 'title' => $lang->block->tooltips['ev'], + 'content' => array('html' => $lang->block->tooltips['ev']), 'placement' => 'bottom', 'type' => 'white', 'className' => 'text-dark border border-light leading-5' @@ -363,7 +363,7 @@ else ( array ( - 'title' => $lang->block->tooltips['ev'], + 'content' => array('html' => $lang->block->tooltips['ev']), 'placement' => 'bottom', 'type' => 'white', 'className' => 'text-dark border border-light leading-5' From 872e6472bd0b988a0edeefd871fde8f857b8d741 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 15:42:46 +0800 Subject: [PATCH 143/235] * zin: fix search-form not hide on switch to other feature item. --- www/js/zui3/zin.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/www/js/zui3/zin.js b/www/js/zui3/zin.js index f22f3d31fa..ea5183074f 100644 --- a/www/js/zui3/zin.js +++ b/www/js/zui3/zin.js @@ -68,11 +68,10 @@ body: (data) => $('body').html(data), title: (data) => document.title = data, main: (data) => $('#main').html(data), - featureBar: (data) => $('#featureBar').html(data), + featureBar: updateFeatureBar, pageCSS: (data) => $('style.zin-page-css').html(data), pageJS: updatePageJS, configJS: updateConfigJS, - activeFeature: (data) => activeNav(data, '#featureBar'), activeMenu: (data) => activeNav(data), navbar: updateNavbar, heading: updateHeading, @@ -244,6 +243,21 @@ layoutNanavbar(); } + function updateFeatureBar(data) + { + const $featureBar = $('#featureBar'); + const isOpenSearch = $featureBar.find('.search-form-toggle.active').length && $featureBar.closest('.show-search-form').length; + $featureBar.html(data); + if(isOpenSearch) + { + const $searchToggle = $featureBar.find('.search-form-toggle'); + if(!$searchToggle.hasClass('active')) + { + zui.toggleSearchForm({module: $searchToggle.data('module'), show: false}); + } + } + } + function updateHeading(data) { const $data = $(data); From ff5001f711548d8e00dd5c6aa5aa1ea9396fc95b Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 15:50:21 +0800 Subject: [PATCH 144/235] * Adjust create a todo page style. --- module/todo/ui/create.html.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/module/todo/ui/create.html.php b/module/todo/ui/create.html.php index 2aaed14516..ff0010c694 100644 --- a/module/todo/ui/create.html.php +++ b/module/todo/ui/create.html.php @@ -362,7 +362,7 @@ formPanel btn ( set::icon('help'), - toggle::tooltip(array('placement' => 'top-start', 'title' => $lang->todo->privateTip)), + toggle::tooltip(array('placement' => 'right', 'title' => $lang->todo->privateTip, 'type' => 'white', 'class-name' => 'text-gray border border-light')), set::square(true), setClass('ghost h-6 mt-0.5 tooltip-btn') ) @@ -372,7 +372,7 @@ formPanel ( formGroup ( - set::width('4/5'), + set::width('5/6'), set(array('id' => 'nameBox', 'required' => true, 'label' => $lang->todo->name, 'class' => 'name-box')), div ( @@ -383,10 +383,17 @@ formPanel ), formGroup ( - set::width('1/5'), + set::width('1/6'), setClass('priBox'), set::label($lang->todo->pri), - priPicker(setID('pri'), set::name('pri'), set::items($lang->todo->priList), set::value(3)) + priPicker + ( + setID('pri'), + set::name('pri'), + set::items($lang->todo->priList), + set::value(3), + set::required(true) + ) ) ), formGroup @@ -415,7 +422,7 @@ formPanel formGroup ( set::label($lang->todo->beginAndEnd), - set::width('1/2'), + set::width('1/3'), inputGroup ( picker From 270ba145d846de301dffa6030d09a1e6d5f33b99 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 15:50:34 +0800 Subject: [PATCH 145/235] * Adjust batch create todo page style. --- module/todo/ui/batchcreate.html.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/todo/ui/batchcreate.html.php b/module/todo/ui/batchcreate.html.php index ecdde54557..1baff35e37 100644 --- a/module/todo/ui/batchcreate.html.php +++ b/module/todo/ui/batchcreate.html.php @@ -89,7 +89,7 @@ formBatchPanel set::name('type'), set::label($lang->todo->type), set::width('120px'), - set::control('picker'), + set::control(array('type' => 'picker', 'required' => true)), set::value('custom'), set::items($lang->todo->typeList) ), @@ -98,7 +98,7 @@ formBatchPanel set::name('pri'), set::label($lang->todo->pri), set::width('80px'), - set::control('priPicker'), + set::control(array('type' => 'priPicker', 'required' => true)), set::value('3'), set::items($lang->todo->priList) ), @@ -121,7 +121,7 @@ formBatchPanel set::value($app->user->account), set::ditto(true), set::width('140px'), - set::control('picker'), + set::control(array('type' => 'picker', 'required' => true)), set::items($users) ), formBatchItem From f0c0180e98f235a51e7c53f44aa13e7dfedd5065 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 15:57:44 +0800 Subject: [PATCH 146/235] * Add required label of the owner field. --- module/kanban/ui/createspace.html.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/kanban/ui/createspace.html.php b/module/kanban/ui/createspace.html.php index 162b7447e0..7a0e34cd61 100644 --- a/module/kanban/ui/createspace.html.php +++ b/module/kanban/ui/createspace.html.php @@ -42,6 +42,7 @@ formPanel formGroup ( set::label($lang->kanbanspace->owner), + set::required(true), picker ( set::name('owner'), From a431fbc95b6dd25fa37dc8ae7894504b23218471 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 16:07:21 +0800 Subject: [PATCH 147/235] * Adjust create a kanban page style. --- module/kanban/ui/create.html.php | 48 ++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/module/kanban/ui/create.html.php b/module/kanban/ui/create.html.php index 70f0be112f..53e1979932 100644 --- a/module/kanban/ui/create.html.php +++ b/module/kanban/ui/create.html.php @@ -68,6 +68,7 @@ formPanel ( set::width('1/2'), set::label($lang->kanban->space), + set::required(true), picker ( set::name('space'), @@ -302,23 +303,40 @@ if($copyKanbanID != 0) ) ); } -foreach ($kanbans as $id => $name) + +if(!empty($kanbans)) { - $kanbanList[] = cell - ( - set::width('1/3'), - set::className('p-2'), - div + foreach ($kanbans as $id => $name) + { + $kanbanList[] = cell + ( + set::width('1/3'), + set::className('p-2'), + div + ( + set('data-on', 'click'), + set('data-call', 'clickCopyCard'), + set('data-params', 'event'), + set('data-id', $id), + set::className('copy-card p-2 border rounded-md'), + icon('kanban', set::className('pr-2')), + $name + ) + ); + } +} +else +{ + $kanbanList[] = div ( - set('data-on', 'click'), - set('data-call', 'clickCopyCard'), - set('data-params', 'event'), - set('data-id', $id), - set::className('copy-card p-2 border rounded-md'), - icon('kanban', set::className('pr-2')), - $name - ) - ); + setClass('inline-flex items-center w-full bg-lighter h-12 mt-2 mb-8'), + icon('exclamation-sign icon-2x pl-2 text-warning'), + span + ( + set::className('font-bold ml-2'), + $lang->kanban->copyNoKanban + ) + ); } modalTrigger From b5b1f9349aaf546cb97bc895f219cae95d445361 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 16:08:03 +0800 Subject: [PATCH 148/235] * Adjust edit a kanban page style. --- module/kanban/ui/edit.html.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/kanban/ui/edit.html.php b/module/kanban/ui/edit.html.php index 64ff25524e..0c16eae310 100644 --- a/module/kanban/ui/edit.html.php +++ b/module/kanban/ui/edit.html.php @@ -24,6 +24,7 @@ formPanel ( set::width('1/2'), set::label($lang->kanban->space), + set::required(true), picker ( set::name('space'), From 4494ad956bfdc040280062bdfa2022ad45555d37 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 16:08:25 +0800 Subject: [PATCH 149/235] * Fix an issue where space field required judgment failed. --- module/kanban/model.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module/kanban/model.php b/module/kanban/model.php index 9f91d93151..ba632da60e 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -2476,6 +2476,7 @@ class kanbanModel extends model ->setDefault('whitelist', '') ->setDefault('displayCards', 0) ->setIF($this->post->import == 'off', 'object', '') + ->cleanINT('space') ->join('whitelist', ',') ->join('team', ',') ->trim('name') @@ -2553,6 +2554,7 @@ class kanbanModel extends model ->setDefault('lastEditedDate', helper::now()) ->setDefault('whitelist', '') ->setDefault('team', '') + ->cleanINT('space') ->join('whitelist', ',') ->join('team', ',') ->trim('name') From beaad6be19f002b620bef92f337ed66f2f7a0369 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 16:10:31 +0800 Subject: [PATCH 150/235] * Add required label of the owner field. --- module/kanban/ui/editspace.html.php | 1 + 1 file changed, 1 insertion(+) diff --git a/module/kanban/ui/editspace.html.php b/module/kanban/ui/editspace.html.php index 7c8bf90b35..1c9f9e8af8 100644 --- a/module/kanban/ui/editspace.html.php +++ b/module/kanban/ui/editspace.html.php @@ -43,6 +43,7 @@ formPanel formGroup ( set::label($lang->kanbanspace->owner), + set::required(true), picker ( set::name('owner'), From 09896a8f539dc2ca1d3718fdbd731bf4c274fa25 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 16:10:37 +0800 Subject: [PATCH 151/235] * Move the code alter name if setCode is true. --- module/product/config/formdata.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/product/config/formdata.php b/module/product/config/formdata.php index f7abb66586..cbf7dda6a0 100644 --- a/module/product/config/formdata.php +++ b/module/product/config/formdata.php @@ -5,6 +5,7 @@ $config->product->form->create = array(); $config->product->form->create['program'] = array('type' => 'int', 'control' => 'select', 'required' => false, 'default' => 0, 'options' => array()); $config->product->form->create['line'] = array('type' => 'int', 'control' => 'select', 'required' => false, 'default' => 0, 'options' => array()); $config->product->form->create['name'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim'); +if(isset($this->config->setCode) && $this->config->setCode == 1) $config->product->form->create['code'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim'); $config->product->form->create['PO'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->create['QD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->create['RD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); @@ -19,13 +20,13 @@ $config->product->form->create['whitelist'] = array('type' => 'array', 'c $config->product->form->create['createdBy'] = array('type' => 'account', 'control' => '', 'required' => false, 'default' => (isset($app->user) && isset($app->user->account)) ? $app->user->account : ''); $config->product->form->create['createdDate'] = array('type' => 'string', 'control' => '', 'required' => false, 'default' => helper::now()); $config->product->form->create['createdVersion'] = array('type' => 'string', 'control' => '', 'required' => false, 'default' => $config->version); -if(isset($this->config->setCode) && $this->config->setCode == 1) $config->product->form->create['code'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim'); if($config->systemMode != 'ALM') unset($config->product->form->create['program'], $config->product->form->create['line']); $config->product->form->edit = array(); $config->product->form->edit['program'] = array('type' => 'int', 'control' => 'select', 'required' => false, 'default' => 0, 'options' => array()); $config->product->form->edit['line'] = array('type' => 'int', 'control' => 'select', 'required' => false, 'default' => 0, 'options' => array()); $config->product->form->edit['name'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim'); +if(isset($this->config->setCode) && $this->config->setCode == 1) $config->product->form->edit['code'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim'); $config->product->form->edit['PO'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->edit['QD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->edit['RD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); @@ -37,7 +38,6 @@ $config->product->form->edit['desc'] = array('type' => 'string', 'control' $config->product->form->edit['acl'] = array('type' => 'string', 'control' => 'radio', 'required' => false, 'default' => 'private', 'width' => 'full', 'options' => $lang->product->aclList); $config->product->form->edit['groups'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'width' => 'full', 'options' => array()); $config->product->form->edit['whitelist'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'width' => 'full', 'filter' => 'join', 'options' => 'users'); -if(isset($this->config->setCode) && $this->config->setCode == 1) $config->product->form->edit['code'] = array('type' => 'string', 'control' => 'text', 'required' => true, 'filter' => 'trim'); if($config->systemMode != 'ALM') unset($config->product->form->edit['program'], $config->product->form->edit['line']); $config->product->form->batchEdit = array(); From 4159f0e9d0dd2c752110dc702de7e05eab6f3724 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 16:13:23 +0800 Subject: [PATCH 152/235] * Add tooltip to scrum overview block. --- module/block/ui/scrumoverviewblock.html.php | 25 ++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/module/block/ui/scrumoverviewblock.html.php b/module/block/ui/scrumoverviewblock.html.php index b0a8aa9c69..9574709ab0 100644 --- a/module/block/ui/scrumoverviewblock.html.php +++ b/module/block/ui/scrumoverviewblock.html.php @@ -21,7 +21,30 @@ foreach($config->block->projectstatistic->items as $module => $items) $unit = $item['unit']; $cellItems[] = item ( - set::name($lang->block->projectstatistic->{$field} . ': '), + set::name + ( + $lang->block->projectstatistic->{$field}, + !isset($lang->block->tooltips[$field]) ? ':' : null + ), + to::suffixName + ( + isset($lang->block->tooltips[$field]) ? icon + ( + setClass('text-light text-sm'), + toggle::tooltip + ( + array + ( + 'title' => $lang->block->tooltips[$field], + 'placement' => 'bottom', + 'type' => 'white', + 'className' => 'text-dark border border-light leading-5' + ) + ), + 'help', + ':' + ) : null + ), span ( setClass('font-bold text-black mr-0.5'), From 145e84517a1d6e73a38b30bd43adc7ef5ff5031e Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 16:12:41 +0800 Subject: [PATCH 153/235] * Fix the activate space language item error. --- module/kanban/ui/activatespace.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kanban/ui/activatespace.html.php b/module/kanban/ui/activatespace.html.php index a6d72cbd36..d097f50e8e 100644 --- a/module/kanban/ui/activatespace.html.php +++ b/module/kanban/ui/activatespace.html.php @@ -9,7 +9,7 @@ declare(strict_types=1); * @link https://www.zentao.net */ namespace zin; -modalHeader(set::title($lang->kanban->activeSpace), set::entityText($space->name), set::entityID($space->id)); +modalHeader(set::title($lang->kanban->activateSpace), set::entityText($space->name), set::entityID($space->id)); formPanel ( From a13c9941f7200b859f33a0c2294d5962a8a9e4bb Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Fri, 17 Nov 2023 16:24:07 +0800 Subject: [PATCH 154/235] * Fix the bug of search. --- module/search/model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/search/model.php b/module/search/model.php index 895ce0affd..79af19cee4 100644 --- a/module/search/model.php +++ b/module/search/model.php @@ -376,9 +376,9 @@ class searchModel extends model * * @param int $queryID * @access public - * @return object + * @return object|bool */ - public function getQuery(int $queryID): object + public function getQuery(int $queryID): object|bool { $query = $this->dao->findByID($queryID)->from(TABLE_USERQUERY)->fetch(); if(!$query) return false; From 5bd560e064126885e9ec3b540f42458c25e5c0f6 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 16:38:07 +0800 Subject: [PATCH 155/235] * Change products to non-required. --- module/project/ui/create.html.php | 1 - 1 file changed, 1 deletion(-) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 94e6d88789..58b8014eb0 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -367,7 +367,6 @@ formPanel set::width('1/2'), set('id', 'linkProduct'), set::label($lang->project->manageProducts), - set::required(true), inputGroup ( div From 0d242d0c0e6505930bcd4b61fd5de66d77991eb7 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 16:17:47 +0800 Subject: [PATCH 156/235] * zin: refactor. --- lib/zin/core/context.class.php | 2 +- lib/zin/core/h.class.php | 8 ++++---- lib/zin/core/selector.func.php | 4 ++-- lib/zin/wg/formsettingbtn/js/v1.js | 8 ++++---- lib/zin/wg/stepseditor/js/v1.js | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/zin/core/context.class.php b/lib/zin/core/context.class.php index 92bd065a4b..69a6418d50 100644 --- a/lib/zin/core/context.class.php +++ b/lib/zin/core/context.class.php @@ -78,7 +78,7 @@ class context extends \zin\utils\dataset public function getEventsBindings() { $wgs = $this->getList('wgWithEvents'); - $codes = []; + $codes = array(); foreach($wgs as $wg) { if(!method_exists($wg, 'buildEvents')) continue; diff --git a/lib/zin/core/h.class.php b/lib/zin/core/h.class.php index ba9fd8f012..dfa2530b50 100644 --- a/lib/zin/core/h.class.php +++ b/lib/zin/core/h.class.php @@ -238,8 +238,8 @@ class h extends wg $args = func_get_args(); $funcName = array_shift($args); - $funcArgs = []; - $directives = []; + $funcArgs = array(); + $directives = array(); foreach($args as $arg) { if(isDirective($arg)) $directives[] = $arg; @@ -304,8 +304,8 @@ class h extends wg protected static function splitRawCode($children) { $children = \zin\utils\flat($children); - $code = []; - $args = []; + $code = array(); + $args = array(); foreach($children as $key => $child) { if(is_string($child)) $code[] = $child; diff --git a/lib/zin/core/selector.func.php b/lib/zin/core/selector.func.php index 71ed8f895c..4a2b8883a1 100644 --- a/lib/zin/core/selector.func.php +++ b/lib/zin/core/selector.func.php @@ -62,7 +62,7 @@ function parseWgSelector(string|object $selector): ?object } elseif($type === 'option') { - $options = []; + $options = array(); parse_str($current, $options); foreach($options as $key => $value) $result[$key] = empty($value) ? true : $value; } @@ -149,7 +149,7 @@ function stringifyWgSelectors(array|object|null $selector): string if(empty($selector)) return ''; if(is_array($selector)) { - $result = []; + $result = array(); foreach($selector as $s) $result[] = stringifyWgSelectors($s); return implode(',', $result); } diff --git a/lib/zin/wg/formsettingbtn/js/v1.js b/lib/zin/wg/formsettingbtn/js/v1.js index 99d25ffa8b..ca112e407b 100644 --- a/lib/zin/wg/formsettingbtn/js/v1.js +++ b/lib/zin/wg/formsettingbtn/js/v1.js @@ -39,8 +39,8 @@ function revertDefaultFields(e) function onSubmitFormtSetting(e) { - const customFields = []; - const showFields = []; + const customFields = array(); + const showFields = array(); const $form = $(e.target).closest('form'); $.post($form.attr('action'), new FormData($form[0]), function(result) @@ -124,8 +124,8 @@ function toggleBatchField(customFields, showFields) { if(typeof customFields == 'undefined') return false; - let hiddenFields = []; - let shownFields = []; + let hiddenFields = array(); + let shownFields = array(); customFields.forEach(function(field) { if($('th.form-batch-head[data-name="' + field + '"]').length == 0) return true; diff --git a/lib/zin/wg/stepseditor/js/v1.js b/lib/zin/wg/stepseditor/js/v1.js index e61ed72f2e..127ca3324b 100644 --- a/lib/zin/wg/stepseditor/js/v1.js +++ b/lib/zin/wg/stepseditor/js/v1.js @@ -194,7 +194,7 @@ class StepsEditor extends zui.Component reset(data, skipRender) { - this._items = []; + this._items = array(); this.update(data, skipRender); } From f48b2d27a45de6dc35a5bab40ecb97984bc92c86 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 16:52:01 +0800 Subject: [PATCH 157/235] * action: update searchform on switch item on featurebar. --- module/action/ui/trash.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/action/ui/trash.html.php b/module/action/ui/trash.html.php index caab03903d..a1cdc7f52b 100644 --- a/module/action/ui/trash.html.php +++ b/module/action/ui/trash.html.php @@ -34,7 +34,7 @@ featureBar ( set::current($currentObjectType), set::linkParams("objectType={key}&type={$type}&byQuery=&queryID=&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"), - li(searchToggle(set::module('trash')), setClass($currentObjectType != 'all' ? '' : 'hidden')) + li(searchToggle(set::module('trash')), setClass($currentObjectType != 'all' ? '' : 'hidden', $byQuery ? 'active' : '')) ); toolbar @@ -79,4 +79,4 @@ dtable set::footPager(usePager()) ); -render(); +jsVar('window.afterPageUpdate', jsRaw("(target,info) => info.name === 'featureBar' && !$(target).find('.active>.search-form-toggle').length && zui.updateSearchForm('trash');")); From f25f236d5b21f2d3fab0f23de58f35a4adcf90a9 Mon Sep 17 00:00:00 2001 From: daitingting Date: Fri, 17 Nov 2023 09:07:19 +0000 Subject: [PATCH 158/235] * Set items for radio. --- module/product/ui/create.html.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/product/ui/create.html.php b/module/product/ui/create.html.php index 8ce8dbb9ee..a4a00adc50 100644 --- a/module/product/ui/create.html.php +++ b/module/product/ui/create.html.php @@ -20,8 +20,8 @@ foreach($fields as $field => $attr) $control = array(); $control['type'] = $attr['control']; - if($attr['control'] == 'select') $control['type'] = 'picker'; - if($attr['control'] == 'radio') $control['type'] = 'radioList'; + if($attr['control'] == 'select') $control['type'] = 'picker'; + if($attr['control'] == 'radio') $control['type'] = 'radioList'; if($attr['control'] == 'multi-select') { $control['type'] = 'picker'; @@ -29,9 +29,9 @@ foreach($fields as $field => $attr) $fieldName .= '[]'; } - if($control['type'] == 'picker') $control['items'] = $attr['options']; + if($control['type'] == 'picker' || $control['type'] == 'radioList') $control['items'] = $attr['options']; - if($field == 'line' and common::hasPriv('product', 'manageLine') and $programID) + if($field == 'line' && hasPriv('product', 'manageLine') && $programID) { $formGroup = formGroup ( From 37e16e56628d071c3d3a393386f66102be3ef96e Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Fri, 17 Nov 2023 17:16:24 +0800 Subject: [PATCH 159/235] * Hide devops search for no devops module. --- module/common/model.php | 6 ++++++ module/search/control.php | 1 + 2 files changed, 7 insertions(+) diff --git a/module/common/model.php b/module/common/model.php index 39f1f4b1bc..6926650b98 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -1294,6 +1294,12 @@ class commonModel extends model $searchObjects = $lang->searchObjects; if($config->systemMode == 'light') unset($searchObjects['program']); + if(!helper::hasFeature('devops')) + { + if(isset($searchObjects['deploy'])) unset($searchObjects['deploy']); + if(isset($searchObjects['service'])) unset($searchObjects['service']); + if(isset($searchObjects['deploystep'])) unset($searchObjects['deploystep']); + } foreach($searchObjects as $key => $value) { diff --git a/module/search/control.php b/module/search/control.php index 4da81716a0..8e0e222bc1 100644 --- a/module/search/control.php +++ b/module/search/control.php @@ -240,6 +240,7 @@ class search extends control { if(!isset($this->lang->search->modules[$objectType])) continue; if($this->config->systemMode == 'light' and $objectType == 'program') continue; + if(!helper::hasFeature('devops') && in_array($objectType, array('deploy', 'service', 'deploystep'))) continue; $typeList[$objectType] = $this->lang->search->modules[$objectType]; } From 912d4ba3941d7186d1fc6bdff9f23d08f0d247eb Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Fri, 17 Nov 2023 17:24:45 +0800 Subject: [PATCH 160/235] * Change to new writing method. --- module/custom/ui/execution.html.php | 2 +- module/custom/ui/flow.html.php | 2 +- module/custom/ui/kanban.html.php | 2 +- module/custom/ui/limittaskdate.html.php | 2 +- module/custom/ui/percent.html.php | 2 +- module/custom/ui/product.html.php | 2 +- module/custom/ui/required.html.php | 4 ++-- module/custom/ui/set.html.php | 22 +++++++++++++++++----- module/story/ui/batchcreate.html.php | 2 +- module/story/ui/linkstories.html.php | 4 ++-- module/story/ui/submitreview.html.php | 4 ++-- 11 files changed, 30 insertions(+), 18 deletions(-) diff --git a/module/custom/ui/execution.html.php b/module/custom/ui/execution.html.php index 02a3f8d8b8..dd4cb72cca 100644 --- a/module/custom/ui/execution.html.php +++ b/module/custom/ui/execution.html.php @@ -17,7 +17,7 @@ div $sidebarMenu, formPanel ( - set::id('closedExecutionForm'), + setID('closedExecutionForm'), set::actions(array('submit')), set::actionsClass('w-2/3'), setClass('flex-auto ml-4'), diff --git a/module/custom/ui/flow.html.php b/module/custom/ui/flow.html.php index 4c79247896..bdee844c1f 100644 --- a/module/custom/ui/flow.html.php +++ b/module/custom/ui/flow.html.php @@ -12,7 +12,7 @@ namespace zin; formPanel ( - set::id('flowForm'), + setID('flowForm'), set::actions(array('submit')), set::actionsClass('w-1/3'), span diff --git a/module/custom/ui/kanban.html.php b/module/custom/ui/kanban.html.php index c0c7fa605c..345d62fd63 100644 --- a/module/custom/ui/kanban.html.php +++ b/module/custom/ui/kanban.html.php @@ -15,7 +15,7 @@ div setClass('flex'), formPanel ( - set::id('closedExecutionForm'), + setID('closedExecutionForm'), set::actions(array('submit')), setClass('flex-auto'), formGroup diff --git a/module/custom/ui/limittaskdate.html.php b/module/custom/ui/limittaskdate.html.php index 045ff2a3a7..bc5736f072 100644 --- a/module/custom/ui/limittaskdate.html.php +++ b/module/custom/ui/limittaskdate.html.php @@ -17,7 +17,7 @@ div $sidebarMenu, formPanel ( - set::id('limitTaskDateForm'), + setID('limitTaskDateForm'), set::actions(array('submit')), set::actionsClass('w-2/3'), setClass('flex-auto ml-4'), diff --git a/module/custom/ui/percent.html.php b/module/custom/ui/percent.html.php index b6dc3ff203..18df4e1978 100644 --- a/module/custom/ui/percent.html.php +++ b/module/custom/ui/percent.html.php @@ -11,7 +11,7 @@ declare(strict_types=1); namespace zin; formPanel ( - set::id('percentForm'), + setID('percentForm'), set::actions(array('submit')), formRow ( diff --git a/module/custom/ui/product.html.php b/module/custom/ui/product.html.php index fdf78404f6..fcf1867a8b 100644 --- a/module/custom/ui/product.html.php +++ b/module/custom/ui/product.html.php @@ -17,7 +17,7 @@ div $sidebarMenu, formPanel ( - set::id('closedProductForm'), + setID('closedProductForm'), set::actions(array('submit')), set::actionsClass('w-2/3'), setClass('flex-auto ml-4'), diff --git a/module/custom/ui/required.html.php b/module/custom/ui/required.html.php index 51bf24743e..c8d0bb853b 100644 --- a/module/custom/ui/required.html.php +++ b/module/custom/ui/required.html.php @@ -51,12 +51,12 @@ if(common::hasPriv('custom', 'resetRequired')) if(!in_array($module, array('productplan', 'release', 'testsuite', 'testreport', 'caselib', 'doc')) && $config->vision == 'rnd') include 'sidebar.html.php'; div ( - set::id('mainContent'), + setID('mainContent'), setClass('row has-sidebar-left'), isset($sidebarMenu) ? $sidebarMenu : null, formPanel ( - set::id('requiredForm'), + setID('requiredForm'), setClass('flex-auto'), setClass(isset($sidebarMenu) ? 'ml-0.5' : null), set::actionsClass('w-1/2'), diff --git a/module/custom/ui/set.html.php b/module/custom/ui/set.html.php index a0d3cf1544..f2a562d553 100644 --- a/module/custom/ui/set.html.php +++ b/module/custom/ui/set.html.php @@ -211,8 +211,14 @@ elseif(($module == 'story' || $module == 'testcase') && $field == 'review') ( 'help', setClass('pl-4 pt-2'), - set('data-toggle', 'tooltip'), - set('data-title', sprintf($lang->custom->notice->forceNotReview, $lang->$module->common)) + setData + ( + array + ( + 'toggle' => 'tooltip', + 'title' => sprintf($lang->custom->notice->forceNotReview, $lang->$module->common) + ) + ) ) ) ); @@ -235,8 +241,14 @@ elseif(($module == 'story' || $module == 'testcase') && $field == 'review') ( 'help', setClass('pl-4 pt-2'), - set('data-toggle', 'tooltip'), - set('data-title', sprintf($lang->custom->notice->forceReview, $lang->$module->common)) + setData + ( + array + ( + 'toggle' => 'tooltip', + 'title' => sprintf($lang->custom->notice->forceReview, $lang->$module->common) + ) + ) ) ) ); @@ -475,7 +487,7 @@ else div ( - set::id('mainContent'), + setID('mainContent'), setClass('row has-sidebar-left'), $sidebarMenu, formPanel diff --git a/module/story/ui/batchcreate.html.php b/module/story/ui/batchcreate.html.php index 1e8ea45ce0..6e00b532ae 100644 --- a/module/story/ui/batchcreate.html.php +++ b/module/story/ui/batchcreate.html.php @@ -41,7 +41,7 @@ formBatchPanel ( on::click('#saveButton', 'customSubmit'), on::click('#saveDraftButton', 'customSubmit'), - set::id('dataform'), + setID('dataform'), $stories ? set::data($stories) : null, set::title($storyID ? $storyTitle . $lang->colon . $this->lang->story->subdivide : $this->lang->story->batchCreate), set::uploadParams('module=story¶ms=' . helper::safe64Encode("productID=$productID&branch=$branch&moduleID=$moduleID&storyID=$storyID&executionID=$executionID&plan=&type=$type")), diff --git a/module/story/ui/linkstories.html.php b/module/story/ui/linkstories.html.php index acdffb08da..a280b47822 100644 --- a/module/story/ui/linkstories.html.php +++ b/module/story/ui/linkstories.html.php @@ -27,10 +27,10 @@ $data = array(); foreach($stories2Link as $story) $data[] = $this->story->formatStoryForList($story); modalHeader(set::title($story->type == 'story' ? $lang->story->linkStoriesAB : $lang->story->linkRequirementsAB)); -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); +div(setID('searchFormPanel'), setData(array('module' => 'story')), searchToggle(set::open(true), set::module('story'))); dtable ( - set::id('linkStories'), + setID('linkStories'), set::userMap($users), set::cols($cols), set::data($data), diff --git a/module/story/ui/submitreview.html.php b/module/story/ui/submitreview.html.php index 90a60e0bcd..2ae8a35115 100644 --- a/module/story/ui/submitreview.html.php +++ b/module/story/ui/submitreview.html.php @@ -20,10 +20,10 @@ if(!$this->story->checkForceReview()) { $needNotReviewBox = span ( - set('class', 'input-group-addon'), + setClass('input-group-addon'), checkbox ( - set::id('needNotReview'), + setID('needNotReview'), set::name('needNotReview'), set::text($lang->story->needNotReview), set::value(1) From e676d101e7a4bc2032b562b7969919a0de45fa3e Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 17:28:02 +0800 Subject: [PATCH 161/235] * Fix bug when installing. --- db/zentao.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/db/zentao.sql b/db/zentao.sql index 83ac34aa26..d0cf9391b8 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -2370,7 +2370,6 @@ INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES (' INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRProduct', '1'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRExecution', '1'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'URSR', '2'); -INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'mode', 'ALM'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'unitList', 'CNY,USD'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'defaultCurrency', 'CNY'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'story', '', 'reviewRules', 'allpass'); @@ -15928,7 +15927,7 @@ CREATE TABLE IF NOT EXISTS `zt_metric` ( `fromID` mediumint(8) unsigned NOT NULL DEFAULT 0, `order` mediumint(8) unsigned NOT NULL DEFAULT '0', `deleted` enum('0','1') NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_metriclib`; From 32fdbb15e7b714d3bd4e38fd048d448aae618b38 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Fri, 17 Nov 2023 17:28:44 +0800 Subject: [PATCH 162/235] * Fix bug of deleting execution. --- module/execution/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/model.php b/module/execution/model.php index 52370a02b6..ea2d81d0b7 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -4963,7 +4963,7 @@ class executionModel extends model public function delete(string $table, int $executionID): void { $this->dao->update($table)->set('deleted')->eq(1)->where('id')->eq($executionID)->exec(); - $this->loadModel('action')->create('execution', $executionID, 'deleted'); + $this->loadModel('action')->create('execution', $executionID, 'deleted', '' , 1); } /* From 37845bd1a932acc61e99fdb2f25023654c3fd61c Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 17 Nov 2023 17:41:48 +0800 Subject: [PATCH 163/235] * Add interactions related to create a kanban. --- module/kanban/css/create.ui.css | 3 ++ module/kanban/js/common.ui.js | 48 ++++++++++++++++++++++++++++++++ module/kanban/js/create.ui.js | 20 +++++++++++++ module/kanban/ui/create.html.php | 22 +++++++++++++-- 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/module/kanban/css/create.ui.css b/module/kanban/css/create.ui.css index 514f40f438..e5e39c5930 100644 --- a/module/kanban/css/create.ui.css +++ b/module/kanban/css/create.ui.css @@ -1,3 +1,6 @@ .panel-form .headingActions {position: absolute; top: 0px; right: 40px;} .copy-card:hover {border-color: rgba(var(--color-secondary-499-rgb),var(--tw-bg-opacity)); background-color: rgba(var(--color-gray-100-rgb),var(--tw-bg-opacity)); cursor: pointer;} #copyKanbanModal .modal-body {margin-left: -8px; margin-right: -8px;} +#fixedColBox .items-center, #autoColBox .items-center {align-items: center !important;} +div.required {position: relative;} +div.required:after {content: '*'; color: rgba(var(--color-danger-500-rgb),var(--tw-text-opacity)); position: absolute; top: 0.5rem; right: -0.5rem;} diff --git a/module/kanban/js/common.ui.js b/module/kanban/js/common.ui.js index c0f5464c53..e93cf50718 100644 --- a/module/kanban/js/common.ui.js +++ b/module/kanban/js/common.ui.js @@ -69,3 +69,51 @@ window.changeKanbanSpace = function() }); } } + +/** + * Handle radio logic of Kanban column width setting. + * + * @access public + * @return void + */ +window.handleKanbanWidthAttr = function() +{ + $('#colWidth, #minColWidth, #maxColWidth').attr('onkeyup', 'value=value.match(/^\\d+$/) ? value : ""'); + $('#colWidth, #minColWidth, #maxColWidth').attr('maxlength', '3'); + let fluidBoard = $(".form input[name='fluidBoard']:checked").val() || 0; + let addAttrEle = fluidBoard == 0 ? '#colWidth' : '#minColWidth, #maxColWidth'; + let $fixedTip = $('#fixedColBox .fixedTip'); + let $autoTip = $('#autoColBox .autoTip'); + $(addAttrEle).closest('.width-radio-row').addClass('required'); + if(fluidBoard == 1) + { + $('#colWidth').attr('disabled', true); + $('#minColWidth, #maxColWidth').removeAttr('disabled'); + } + else + { + $('#colWidth').removeAttr('disabled'); + $('#minColWidth, #maxColWidth').attr('disabled', true); + } + + $(document).on("#minColWidth, #maxColWidth", 'input', function() + { + $('#minColWidthLabel, #maxColWidthLabel').remove(); + $('#minColWidth, #maxColWidth').removeClass('has-error'); + }); + + if(fluidBoard == 1) + { + $fixedTip.addClass('hidden'); + $autoTip.removeClass('hidden'); + $('#colWidth').closest('div').removeClass('required'); + $('#maxColWidth').closest('div').addClass('required'); + } + else + { + $fixedTip.removeClass('hidden'); + $autoTip.addClass('hidden'); + $('#colWidth').closest('div').addClass('required'); + $('#maxColWidth').closest('div').removeClass('required'); + } +} diff --git a/module/kanban/js/create.ui.js b/module/kanban/js/create.ui.js index ea8c6f3a5a..060e911413 100644 --- a/module/kanban/js/create.ui.js +++ b/module/kanban/js/create.ui.js @@ -9,3 +9,23 @@ window.setCopyKanban = function(kanbanID) const url = $.createLink('kanban', 'create', 'spaceID=' + spaceID + '&type=' + spaceType + '©KanbanID=' + kanbanID); loadPartial(url, '#WIPCountBox, #spaceBox, #nameBox, #ownerBox, #teamBox, #fixedColBox, #autoColBox, #archiveBox, #manageProgressBox, #alignmentBox, #descBox, #whitelistBox'); } + +window.toggleImportObjectBox = function(e) +{ + let isImport = $(e.target).val() == 'on'; + if(!isImport) + { + $("input[name^='importObjectList']").attr('disabled', 'disabled'); + $('#objectBox').hide(); + } + else + { + $("input[name^='importObjectList']").removeAttr('disabled'); + $('#objectBox').show(); + } +} + +window.waitDom('input[name=fluidBoard]', function() +{ + handleKanbanWidthAttr(); +}); diff --git a/module/kanban/ui/create.html.php b/module/kanban/ui/create.html.php index 53e1979932..749d14bfd4 100644 --- a/module/kanban/ui/create.html.php +++ b/module/kanban/ui/create.html.php @@ -138,12 +138,14 @@ formPanel set::id('fixedColBox'), formGroup ( + setClass('items-center'), set::label($lang->kanban->columnWidth), radioList ( set::name('fluidBoard'), set::items(array('0' => $lang->kanbancolumn->fluidBoardList[0])), - set::value(isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0) + set::value(isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0), + on::change('handleKanbanWidthAttr') ), div ( @@ -152,6 +154,11 @@ formPanel span($lang->kanban->colWidth), input(set::type('number'), set::min($config->colWidth), set::name('colWidth'), set::className('w-16 size-sm mx-1'), set::value(isset($copyKanban->colWidth) ? $copyKanban->colWidth : $config->colWidth)), span('px') + ), + div + ( + setClass('fixedTip ml-4 text-primary'), + $lang->kanbancolumn->fixedTip ) ) @@ -162,12 +169,14 @@ formPanel set::style(array('margin-top' => '0px')), formGroup ( + setClass('items-center'), set::label(''), radioList ( set::name('fluidBoard'), set::items(array(1 => $lang->kanbancolumn->fluidBoardList[1])), - set::value(isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0) + set::value(isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0), + on::change('handleKanbanWidthAttr') ), div ( @@ -178,6 +187,11 @@ formPanel span('~', set::className('mx-1')), input(set::type('number'), set::min($config->maxColWidth), set::name('maxColWidth'), set::className('w-16 size-sm mx-1'), set::value(isset($copyKanban->maxColWidth) ? $copyKanban->maxColWidth : $config->maxColWidth)), span('px') + ), + div + ( + setClass('autoTip hidden ml-4 text-primary'), + $lang->kanbancolumn->autoTip ) ) ), @@ -191,13 +205,15 @@ formPanel set::name('import'), set::items($lang->kanban->importList), set::inline(true), - set::value($enableImport) + set::value($enableImport), + on::change('toggleImportObjectBox') ) ) ), formRow ( set::style(array('margin-top' => '0px')), + setID('objectBox'), formGroup ( set::label(''), From 008308fd8f2e50d0255ce0821ef70ff75db17ed1 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 17:19:47 +0800 Subject: [PATCH 164/235] * zin: fix loadTarget not work with only one obejct options. --- www/js/zui3/zin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/js/zui3/zin.js b/www/js/zui3/zin.js index ea5183074f..e0aba80c7e 100644 --- a/www/js/zui3/zin.js +++ b/www/js/zui3/zin.js @@ -738,7 +738,7 @@ const ajaxOptions = { - url: url, + url: options.url, header: options.header, type: options.method || 'GET', data: options.data, From 7c4c44389753934d66956d3b68112a62b103faf2 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 17:20:25 +0800 Subject: [PATCH 165/235] * zin/detailbody: refactor, prevent to generate empty element. --- lib/zin/wg/detailbody/v1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zin/wg/detailbody/v1.php b/lib/zin/wg/detailbody/v1.php index ec8dc08cb8..e0e31dafca 100644 --- a/lib/zin/wg/detailbody/v1.php +++ b/lib/zin/wg/detailbody/v1.php @@ -44,7 +44,7 @@ class detailBody extends wg setClass('col gap-1 grow'), $main, $bottom, - center(setClass('pt-6'), $floating) + empty($floating) ? null : center(setClass('pt-6'), $floating) ), $side ); From ca11b7531ab6a56975d131bba105b5c199832c02 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 18:48:12 +0800 Subject: [PATCH 166/235] * productplan: refactor with the SearchForm component. --- module/productplan/css/view.ui.css | 2 -- module/productplan/js/view.ui.js | 29 ++++++++++----- module/productplan/ui/linkbug.html.php | 10 +++++- module/productplan/ui/linkstory.html.php | 10 +++++- module/productplan/ui/view.html.php | 46 +++++++++++++++++------- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/module/productplan/css/view.ui.css b/module/productplan/css/view.ui.css index b90df12f01..467f88471b 100644 --- a/module/productplan/css/view.ui.css +++ b/module/productplan/css/view.ui.css @@ -1,5 +1,3 @@ -.tab-actions {float:right; margin-top: -55px;} -.tab-actions .primary {margin-left:8px;} #mainContent .detail-body .section-list .tabs ul {border-bottom-width: 1px; border-bottom-style: solid;} #mainContent .detail-body .section-list .tab-content .table-data caption {padding-top: 16px;} #planInfo table caption {font-size: 1rem; font-weight: bold;} diff --git a/module/productplan/js/view.ui.js b/module/productplan/js/view.ui.js index ea0e1950a0..5e0db198a3 100644 --- a/module/productplan/js/view.ui.js +++ b/module/productplan/js/view.ui.js @@ -28,11 +28,22 @@ window.ajaxConfirmLoad = function(obj) }); }; -window.showLink = function(obj) +window.showLink = function(type, params, onlyUpdateTable) { - var $this = $(obj); - var idName = $this.data('type') == 'story' ? '#stories' : '#bugs'; - $(idName).load($this.data('linkurl')); + const url = $.createLink('productplan', type === 'story' ? 'linkStory' : 'linkBug', 'planID=' + planID + (params || '&browseType=¶m=')); + if(onlyUpdateTable) + { + loadComponent($('#' + (type === 'story' ? 'stories' : 'bugs')).find('.dtable').attr('id'), {url: url, component: 'dtable'}); + return; + } + loadTarget({url: url, target: type === 'story' ? 'stories' : 'bugs'}); +}; + +window.onSearchLinks = function(type, result) +{ + const params = $.parseLink(result.load).vars[4]; + showLink(type, params ? atob(params[1]) : null, true); + return false; }; $(document).off('click', '.batch-btn > a, .batch-btn').on('click', '.batch-btn > a, .batch-btn', function() @@ -72,8 +83,10 @@ $(document).on('click', '.linkObjectBtn', function() $.ajaxSubmit({"url": $(this).data('url'), "data": postData}); }); -if(initLink == 'true') +$(function() { - var idName = type == 'story' ? '#stories' : '#bugs'; - window.showLink($(idName).find('.link')); -} + if(initLink == 'true') + { + window.showLink(type, linkParams); + } +}) diff --git a/module/productplan/ui/linkbug.html.php b/module/productplan/ui/linkbug.html.php index 6145c27b9d..9f66f8ff69 100644 --- a/module/productplan/ui/linkbug.html.php +++ b/module/productplan/ui/linkbug.html.php @@ -15,7 +15,14 @@ foreach($config->productplan->defaultFields['linkBug'] as $field) $cols[$field] $cols = array_map(function($col){$col['show'] = true; return $col;}, $cols); $cols['assignedTo']['type'] = 'user'; -div(setID('searchFormPanel'), set('data-module', 'bug'), searchToggle(set::open(true), set::module('bug'))); +searchForm +( + set::module('bug'), + set::simple(true), + set::show(true), + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'bug')")) +); + dtable ( set::id('unlinkBugList'), @@ -23,6 +30,7 @@ dtable set::checkable(true), set::cols($cols), set::data(array_values($allBugs)), + set::extraHeight('+144'), set::footToolbar(array ( 'items' => array(array diff --git a/module/productplan/ui/linkstory.html.php b/module/productplan/ui/linkstory.html.php index cf0afe3b91..d7f028f2f9 100644 --- a/module/productplan/ui/linkstory.html.php +++ b/module/productplan/ui/linkstory.html.php @@ -22,7 +22,14 @@ $cols['module']['map'] = $modules; foreach($allStories as $story) $story->estimate = $story->estimate . $config->hourUnit; -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); +searchForm +( + set::module('story'), + set::simple(true), + set::show(true), + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'story')")) +); + dtable ( set::id('unlinkStoryList'), @@ -30,6 +37,7 @@ dtable set::cols($cols), set::data(array_values($allStories)), set::onRenderCell(jsRaw('window.renderStoryCell')), + set::extraHeight('+144'), set::footToolbar(array('items' => array(array ( 'text' => $lang->productplan->linkStory, diff --git a/module/productplan/ui/view.html.php b/module/productplan/ui/view.html.php index 7a4e8f6eac..f85c6cf822 100644 --- a/module/productplan/ui/view.html.php +++ b/module/productplan/ui/view.html.php @@ -20,15 +20,17 @@ $confirmLang['finish'] = $lang->productplan->confirmFinish; $confirmLang['activate'] = $lang->productplan->confirmActivate; $confirmLang['delete'] = $lang->productplan->confirmDelete; +$decodeParam = helper::safe64Decode($param); + jsVar('initLink', $link); jsVar('type', $type); +jsVar('linkParams', $decodeParam); jsVar('orderBy', $orderBy); jsVar('planID', $plan->id); jsVar('confirmLang', $confirmLang); jsVar('unlinkURL', $unlinkURL); jsVar('childrenAB', $lang->story->childrenAB); -$decodeParam = helper::safe64Decode($param); $bugCols = array(); $storyCols = array(); foreach($config->productplan->defaultFields['story'] as $field) $storyCols[$field] = zget($config->story->dtable->fieldList, $field, array()); @@ -173,16 +175,17 @@ detailBody ( tabs ( - setClass('w-full'), + setClass('w-full relative'), tabPane ( - to::prefix(icon($lang->icons['story'])), + to::prefix(icon($lang->icons['story'], setClass('text-secondary'))), set::key('stories'), set::title($lang->productplan->linkedStories), set::active($type == 'story'), - div + toolbar ( - setClass('tab-actions'), + setClass('tab-actions absolute right-0 gap-2'), + setStyle('top', '-8px'), dropdown ( btn(set::text($lang->story->create), set::target('_parent'), setClass('secondary' . (empty($createStoryLink) ? ' disabled' : '')), set::icon('plus'), set::caret(true), set::url($createStoryLink)), @@ -190,7 +193,15 @@ detailBody set::trigger('hover'), set::placement('bottom-end') ), - !common::hasPriv('productplan', 'linkStory') ? null : btn(set::text($lang->productplan->linkStory), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'story'), set('data-linkurl', inlink('linkStory', "planID={$plan->id}" . (($link == 'true' && $type == 'story') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}"))) + common::hasPriv('productplan', 'linkStory') ? btn + ( + set::type('primary'), + set::icon('link'), + set::text($lang->productplan->linkStory), + bind::click("window.showLink('story')") + // set::url(inlink('linkStory', "planID={$plan->id}" . (($link == 'true' && $type == 'story') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}")), + // setData(array('load' => 'target', 'target' => '#stories')) + ) : null ), dtable ( @@ -204,6 +215,7 @@ detailBody set::footToolbar($storyFootToolbar), set::sortLink(createLink('productplan', 'view', "planID={$plan->id}&type=story&orderBy={name}_{sortType}&link=false¶m={$param}&recTotal={$storyPager->recTotal}&recPerPage={$storyPager->recPerPage}&page={$storyPager->pageID}")), set::orderBy($orderBy), + set::extraHeight('+144'), set::footer(array('checkbox', 'toolbar', array('html' => $summary, 'className' => "text-dark"), 'flex', 'pager')), set::footPager ( @@ -212,19 +224,28 @@ detailBody 'recTotal' => $storyPager->recTotal, 'linkCreator' => helper::createLink('productplan', 'view', "planID={$plan->id}&type=story&orderBy={$orderBy}&link=false¶m={$param}&recTotal={$storyPager->recTotal}&recPerPage={recPerPage}&page={page}") )) - ), + ) ) ), tabPane ( - to::prefix(icon(setClass('text-red'), $lang->icons['bug'])), + to::prefix(icon($lang->icons['bug'], setClass('text-danger'))), set::key('bugs'), set::title($lang->productplan->linkedBugs), set::active($type == 'bug'), - div + toolbar ( - setClass('tab-actions'), - !common::hasPriv('productplan', 'linkBug') ? null : btn(set::text($lang->productplan->linkBug), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'bug'), set('data-linkurl', inlink('linkBug', "planID={$plan->id}" . (($link == 'true' && $type == 'bug') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}"))) + setClass('tab-actions absolute right-0 gap-2'), + setStyle('top', '-8px'), + common::hasPriv('productplan', 'linkBug') ? btn + ( + set::type('primary'), + set::icon('link'), + set::text($lang->productplan->linkBug), + bind::click("window.showLink('bug')") + // set::url(inlink('linkBug', "planID={$plan->id}" . (($link == 'true' && $type == 'bug') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}")), + // setData(array('load' => 'target', 'target' => '#bugs')) + ) : null ), dtable ( @@ -237,6 +258,7 @@ detailBody set::footToolbar($bugFootToolbar), set::sortLink(createLink('productplan', 'view', "planID={$plan->id}&type=bug&orderBy={name}_{sortType}&link=false¶m={$param}&recTotal={$bugPager->recTotal}&recPerPage={$bugPager->recPerPage}&page={$bugPager->pageID}")), set::orderBy($orderBy), + set::extraHeight('+144'), set::footer(array('checkbox', 'toolbar', array('html' => sprintf($lang->productplan->bugSummary, count($planBugs)), 'className' => "text-dark"), 'flex', 'pager')), set::footPager ( @@ -250,7 +272,7 @@ detailBody ), tabPane ( - to::prefix(icon(setClass('text-info'), 'info')), + to::prefix(icon('flag', setClass('text-special'))), set::key('planInfo'), set::title($lang->productplan->view), set::active($type == 'planInfo'), From 4ee13a8a71290f37e9a85d4f1b85285935d9e9c5 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 22:29:22 +0800 Subject: [PATCH 167/235] * refactor linkXxx with searchForm. --- module/build/ui/linkbug.html.php | 9 ++++++++- module/build/ui/linkstory.html.php | 9 ++++++++- module/mr/ui/linkbug.html.php | 7 ++++++- module/mr/ui/linkstory.html.php | 7 ++++++- module/mr/ui/linktask.html.php | 7 ++++++- module/release/ui/linkstory.html.php | 8 +++++++- module/repo/ui/linkbug.html.php | 7 ++++++- module/repo/ui/linkstory.html.php | 7 ++++++- module/repo/ui/linktask.html.php | 7 ++++++- module/story/ui/edit.html.php | 20 ++++++++++++++++++-- module/story/ui/linkstories.html.php | 9 ++++++++- module/story/ui/linkstory.html.php | 9 ++++++++- module/testcase/ui/importfromlib.html.php | 12 ++++-------- module/testcase/ui/linkcases.html.php | 12 ++++-------- 14 files changed, 101 insertions(+), 29 deletions(-) diff --git a/module/build/ui/linkbug.html.php b/module/build/ui/linkbug.html.php index 0e20d1673e..ca6651096e 100644 --- a/module/build/ui/linkbug.html.php +++ b/module/build/ui/linkbug.html.php @@ -28,7 +28,13 @@ foreach($config->build->defaultFields['linkBug'] as $field) } $cols = array_map(function($col){$col['show'] = true; return $col;}, $cols); -div(setID('searchFormPanel'), setData(array('module' => 'bug')), searchToggle(set::open(true), set::module('bug'))); +searchForm +( + set::module('bug'), + set::simple(true), + set::show(true) +); + dtable ( setID('unlinkBugList'), @@ -36,6 +42,7 @@ dtable set::checkable(true), set::cols($cols), set::data(array_values($allBugs)), + set::extraHeight('+144'), set::onRenderCell(jsRaw('window.renderBugCell')), set::plugins(array('form')), set::footToolbar(array diff --git a/module/build/ui/linkstory.html.php b/module/build/ui/linkstory.html.php index c8a1a5f98c..568b9d45ba 100644 --- a/module/build/ui/linkstory.html.php +++ b/module/build/ui/linkstory.html.php @@ -24,13 +24,20 @@ foreach($allStories as $story) $story->estimate = $story->estimate . $config->hourUnit; } -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); +searchForm +( + set::module('story'), + set::simple(true), + set::show(true) +); + dtable ( set::id('unlinkStoryList'), set::userMap($users), set::cols($cols), set::data(array_values($allStories)), + set::extraHeight('+144'), set::onRenderCell(jsRaw('window.renderStoryCell')), set::footToolbar(array('items' => array(array ( diff --git a/module/mr/ui/linkbug.html.php b/module/mr/ui/linkbug.html.php index d056d78b1e..14461afa33 100644 --- a/module/mr/ui/linkbug.html.php +++ b/module/mr/ui/linkbug.html.php @@ -18,7 +18,12 @@ $footToolbar = array('items' => array array('text' => $lang->productplan->linkBug, 'className' => 'batch-btn ajax-btn', 'data-url' => helper::createLink('mr', 'linkBug', "MRID=$MRID&productID=$product->id&browseType=$browseType¶m=$param&orderBy=$orderBy")) ), 'btnProps' => array('size' => 'sm', 'btnType' => 'secondary', 'data-type' => 'bugs')); -div(setID('searchFormPanel'), set('data-module', 'bug'), searchToggle(set::open(true), set::module('bug'))); +searchForm +( + set::module('bug'), + set::simple(true), + set::show(true) +); div ( diff --git a/module/mr/ui/linkstory.html.php b/module/mr/ui/linkstory.html.php index ec9d4c5e3b..ed9ccca449 100644 --- a/module/mr/ui/linkstory.html.php +++ b/module/mr/ui/linkstory.html.php @@ -18,7 +18,12 @@ $footToolbar = array('items' => array array('text' => $lang->mr->linkStory, 'className' => 'batch-btn ajax-btn', 'data-url' => helper::createLink('mr', 'linkStory', "MRID=$MRID&productID=$product->id&browseType=$browseType¶m=$param&orderBy=$orderBy")) ), 'btnProps' => array('size' => 'sm', 'btnType' => 'secondary', 'data-type' => 'stories')); -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); +searchForm +( + set::module('story'), + set::simple(true), + set::show(true) +); div ( diff --git a/module/mr/ui/linktask.html.php b/module/mr/ui/linktask.html.php index 79c0ffab82..8b97b65e29 100644 --- a/module/mr/ui/linktask.html.php +++ b/module/mr/ui/linktask.html.php @@ -27,7 +27,12 @@ $footToolbar = array('items' => array array('text' => $lang->repo->linkTask, 'className' => 'batch-btn ajax-btn', 'data-url' => helper::createLink('mr', 'linkTask', "MRID=$MRID&productID=$product->id&browseType=$browseType¶m=$param&orderBy=$orderBy")) ), 'btnProps' => array('size' => 'sm', 'btnType' => 'secondary', 'data-type' => 'tasks')); -div(setID('searchFormPanel'), set('data-module', 'task'), searchToggle(set::open(true), set::module('task'))); +searchForm +( + set::module('task'), + set::simple(true), + set::show(true) +); div ( diff --git a/module/release/ui/linkstory.html.php b/module/release/ui/linkstory.html.php index a583130f7f..25910af60f 100644 --- a/module/release/ui/linkstory.html.php +++ b/module/release/ui/linkstory.html.php @@ -18,7 +18,13 @@ $cols = array_map(function($col){$col['show'] = true; return $col;}, $cols); $cols['title']['link'] = $this->createLink('story', 'view', "storyID={id}"); $cols['title']['nestedToggle'] = false; -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); +searchForm +( + set::module('story'), + set::simple(true), + set::show(true) +); + dtable ( set::id('unlinkStoryList'), diff --git a/module/repo/ui/linkbug.html.php b/module/repo/ui/linkbug.html.php index 659c5b10bd..54c7d626e3 100644 --- a/module/repo/ui/linkbug.html.php +++ b/module/repo/ui/linkbug.html.php @@ -27,7 +27,12 @@ $footToolbar = array('items' => array array('text' => $lang->productplan->linkBug, 'className' => 'batch-btn ajax-btn', 'data-url' => helper::createLink('repo', 'linkBug', "repoID=$repoID&revision=$revision&browseType=$browseType¶m=$param&orderBy=$orderBy")) ), 'btnProps' => array('size' => 'sm', 'btnType' => 'secondary', 'data-type' => 'bugs')); -div(setID('searchFormPanel'), set('data-module', 'bug'), searchToggle(set::open(true), set::module('bug'))); +searchForm +( + set::module('bug'), + set::simple(true), + set::show(true) +); div ( diff --git a/module/repo/ui/linkstory.html.php b/module/repo/ui/linkstory.html.php index dcda102dd4..32e5529a0a 100644 --- a/module/repo/ui/linkstory.html.php +++ b/module/repo/ui/linkstory.html.php @@ -27,7 +27,12 @@ $footToolbar = array('items' => array array('text' => $lang->repo->linkStory, 'className' => 'batch-btn ajax-btn', 'data-url' => helper::createLink('repo', 'linkStory', "repoID=$repoID&revision=$revision&browseType=$browseType¶m=$param&orderBy=$orderBy")) ), 'btnProps' => array('size' => 'sm', 'btnType' => 'secondary', 'data-type' => 'stories')); -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); +searchForm +( + set::module('story'), + set::simple(true), + set::show(true) +); div ( diff --git a/module/repo/ui/linktask.html.php b/module/repo/ui/linktask.html.php index 019eac6494..d34c7fcb87 100644 --- a/module/repo/ui/linktask.html.php +++ b/module/repo/ui/linktask.html.php @@ -27,7 +27,12 @@ $footToolbar = array('items' => array array('text' => $lang->repo->linkTask, 'className' => 'batch-btn ajax-btn', 'data-url' => helper::createLink('repo', 'linkTask', "repoID=$repoID&revision=$revision&browseType=$browseType¶m=$param&orderBy=$orderBy")) ), 'btnProps' => array('size' => 'sm', 'btnType' => 'secondary', 'data-type' => 'tasks')); -div(setID('searchFormPanel'), set('data-module', 'task'), searchToggle(set::open(true), set::module('task'))); +searchForm +( + set::module('task'), + set::simple(true), + set::show(true) +); div ( diff --git a/module/story/ui/edit.html.php b/module/story/ui/edit.html.php index 85616197c5..846267bb8c 100644 --- a/module/story/ui/edit.html.php +++ b/module/story/ui/edit.html.php @@ -401,8 +401,24 @@ detailBody item ( set::name($story->type == 'story' ? $lang->requirement->linkStory : $lang->story->linkStory), - (common::hasPriv('story', 'linkStories') && $story->type == 'story') ? btn(setClass('secondary'), set::id('linkStoriesLink'), set('data-toggle', 'modal'), set('data-size', 'lg'), on::click('linkStories'), $lang->story->linkStoriesAB) : null, - (common::hasPriv('requirement', 'linkRequirements') && $story->type == 'requirement') ? btn(setClass('secondary'), set::id('linkStoriesLink'), set('data-toggle', 'modal'), set('data-size', 'lg'), on::click('linkStories'), $lang->story->linkRequirementsAB) : null + ($story->type == 'story' && common::hasPriv('story', 'linkStories')) ? btn + ( + setClass('secondary'), + set::id('linkStoriesLink'), + set('data-toggle', 'modal'), + set('data-size', 'lg'), + on::click('linkStories'), + $lang->story->linkStoriesAB + ) : null, + ($story->type == 'requirement' && common::hasPriv('requirement', 'linkRequirements')) ? btn + ( + setClass('secondary'), + set::id('linkStoriesLink'), + set('data-toggle', 'modal'), + set('data-size', 'lg'), + on::click('linkStories'), + $lang->story->linkRequirementsAB + ) : null ), item ( diff --git a/module/story/ui/linkstories.html.php b/module/story/ui/linkstories.html.php index a280b47822..1f3cb818c3 100644 --- a/module/story/ui/linkstories.html.php +++ b/module/story/ui/linkstories.html.php @@ -27,7 +27,14 @@ $data = array(); foreach($stories2Link as $story) $data[] = $this->story->formatStoryForList($story); modalHeader(set::title($story->type == 'story' ? $lang->story->linkStoriesAB : $lang->story->linkRequirementsAB)); -div(setID('searchFormPanel'), setData(array('module' => 'story')), searchToggle(set::open(true), set::module('story'))); + +searchForm +( + set::module('story'), + set::simple(true), + set::show(true) +); + dtable ( setID('linkStories'), diff --git a/module/story/ui/linkstory.html.php b/module/story/ui/linkstory.html.php index d147240b03..4b4d8fff23 100644 --- a/module/story/ui/linkstory.html.php +++ b/module/story/ui/linkstory.html.php @@ -30,7 +30,14 @@ $data = array(); foreach($stories2Link as $story) $data[] = $this->story->formatStoryForList($story); modalHeader(set::title($lang->story->linkStory)); -div(setID('searchFormPanel'), set('data-module', 'story'), searchToggle(set::open(true), set::module('story'))); + +searchForm +( + set::module('story'), + set::simple(true), + set::show(true) +); + dtable ( set::id('linkStories'), diff --git a/module/testcase/ui/importfromlib.html.php b/module/testcase/ui/importfromlib.html.php index b813f15a4c..19d7c978f3 100644 --- a/module/testcase/ui/importfromlib.html.php +++ b/module/testcase/ui/importfromlib.html.php @@ -38,15 +38,11 @@ featureBar ) ); -div +searchForm ( - setID('searchFormPanel'), - set('data-module', 'testsuite'), - searchToggle - ( - set::open(true), - set::module('testsuite') - ) + set::module('testsuite'), + set::simple(true), + set::show(true) ); $config->testcase->importfromlib->dtable->fieldList['fromModule']['map'] = $libModules; diff --git a/module/testcase/ui/linkcases.html.php b/module/testcase/ui/linkcases.html.php index 297c3733b2..5298279e1f 100644 --- a/module/testcase/ui/linkcases.html.php +++ b/module/testcase/ui/linkcases.html.php @@ -17,15 +17,11 @@ modalHeader set::entityID($case->id) ); -div +searchForm ( - setID('searchFormPanel'), - set('data-module', 'testcase'), - searchToggle - ( - set::open(true), - set::module('testcase') - ) + set::module('testcase'), + set::simple(true), + set::show(true) ); $footToolbar = array('items' => array(array('text' => $lang->save, 'btnType' => 'secondary', 'className' => 'link-btn'))); From b1ec59fe6fbcf388df4cc5a7ecc8d360ec478408 Mon Sep 17 00:00:00 2001 From: sunhao Date: Fri, 17 Nov 2023 23:00:38 +0800 Subject: [PATCH 168/235] * gitlab: fix formData not clean after switch feature tab. --- module/gitlab/js/binduser.ui.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/module/gitlab/js/binduser.ui.js b/module/gitlab/js/binduser.ui.js index d25da5436f..338097a421 100644 --- a/module/gitlab/js/binduser.ui.js +++ b/module/gitlab/js/binduser.ui.js @@ -36,3 +36,14 @@ window.bindUser = function(e) data: postData }); } + +window.onPageRender = function(info) +{ + if(info.name === 'dtable') + { + const dtable = zui.DTable.query('#table-gitlab-binduser'); + + /* Clear saved formData. */ + if(dtable) dtable.$.data.formData = {}; + } +}; From 85b8f46da9c6ae56850e90d7f4591b6fe191cbed Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 08:44:42 +0800 Subject: [PATCH 169/235] * Remove unused code. --- module/execution/ui/ajaxgetcopyprojectexecutions.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php index 038e9402ca..8741e6289e 100644 --- a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php +++ b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php @@ -18,7 +18,7 @@ if(empty($executions)) $executionsBox[] = div ( setClass('inline-flex items-center'), - setClass(empty($executions) ? 'bg-lighter h-12' : ''), + setClass('bg-lighter h-12'), icon('exclamation-sign icon-2x pl-2 text-warning'), span ( From a3622cac8809b54f712c0ee237ad3aea32f5fa42 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 08:44:53 +0800 Subject: [PATCH 170/235] * Format projectID. --- module/execution/js/create.ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/execution/js/create.ui.js b/module/execution/js/create.ui.js index 2878b6a93a..eea7620cb7 100644 --- a/module/execution/js/create.ui.js +++ b/module/execution/js/create.ui.js @@ -77,8 +77,8 @@ $(document).on('change', '#end', function(e) */ function loadProjectExecutions(projectID) { - projectID = parseInt(projectID) ? projectID : $('#copyExecutionModal input[name=project]').val(); - if(!projectID) return; + projectID = projectID ? projectID : $('#copyExecutionModal input[name=project]').val(); + projectID = parseInt(projectID); loadTarget($.createLink('execution', 'ajaxGetCopyProjectExecutions', 'projectID=' + projectID + '©ExecutionID=' + copyExecutionID), '#copyExecutions'); } From 6506b253cf1a8c5a2f482bf638d6da0c72773064 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 08:50:04 +0800 Subject: [PATCH 171/235] * Remove empty item in bug::batchCreate and bug::batchEdit. --- module/bug/ui/batchcreate.html.php | 4 ++-- module/bug/ui/batchedit.html.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/bug/ui/batchcreate.html.php b/module/bug/ui/batchcreate.html.php index 524083d2f9..46a00db300 100644 --- a/module/bug/ui/batchcreate.html.php +++ b/module/bug/ui/batchcreate.html.php @@ -83,10 +83,10 @@ $items[] = array('name' => 'steps', 'label' => $lang->bug->steps, 'width' => '24 $items[] = array('name' => 'type', 'label' => $lang->typeAB, 'control' => 'picker', 'items' => $lang->bug->typeList, 'value' => '', 'width' => '160px', 'required' => isset($requiredFields['type']), 'ditto' => true); /* Field of pri. */ -$items[] = array('name' => 'pri', 'label' => $lang->bug->pri, 'control' => 'priPicker', 'items' => $lang->bug->priList, 'value' => 3, 'width' => '100px', 'required' => isset($requiredFields['pri']), 'ditto' => true); +$items[] = array('name' => 'pri', 'label' => $lang->bug->pri, 'control' => array('type' => 'priPicker', 'required' => true), 'items' => $lang->bug->priList, 'value' => 3, 'width' => '100px', 'required' => isset($requiredFields['pri']), 'ditto' => true); /* Field of severity. */ -$items[] = array('name' => 'severity', 'label' => $lang->bug->severity, 'control' => 'severityPicker', 'items' => $lang->bug->severityList, 'value' => 3, 'width' => '80px', 'required' => isset($requiredFields['severity'])); +$items[] = array('name' => 'severity', 'label' => $lang->bug->severity, 'control' => array('type' => 'severityPicker', 'required' => true), 'items' => $lang->bug->severityList, 'value' => 3, 'width' => '80px', 'required' => isset($requiredFields['severity'])); /* Field of os. */ $items[] = array('name' => 'os', 'label' => $lang->bug->os, 'control' => 'picker', 'items' => $lang->bug->osList, 'width' => '200px', 'multiple' => true, 'required' => isset($requiredFields['os'])); diff --git a/module/bug/ui/batchedit.html.php b/module/bug/ui/batchedit.html.php index 2813b4f62e..f78fc38184 100644 --- a/module/bug/ui/batchedit.html.php +++ b/module/bug/ui/batchedit.html.php @@ -76,7 +76,7 @@ formBatchPanel set::name('severity'), set::label($lang->bug->severity), set::hidden(zget($visibleFields, 'severity', true, false)), - set::control('severityPicker'), + set::control(array('type' => 'severityPicker', 'required' => true)), set::items($lang->bug->severityList), set::width('80px'), set::required(isset($requiredFields['severity'])) @@ -87,7 +87,7 @@ formBatchPanel set::name('pri'), set::label($lang->bug->pri), set::hidden(zget($visibleFields, 'pri', true, false)), - set::control('priPicker'), + set::control(array('type' => 'priPicker', 'required' => true)), set::items($lang->bug->priList), set::width('80px'), set::required(isset($requiredFields['pri'])) From c43b399c6a580c4e62eb86bf1b65442e58d228e9 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 20 Nov 2023 08:57:10 +0800 Subject: [PATCH 172/235] * Rewrite account create method. --- module/account/config/form.php | 13 +++++++++++ module/account/control.php | 15 +++++------- module/account/model.php | 23 ++++++++++-------- module/account/test/model/create.php | 35 ++++++++++++++++++++++++++++ module/account/zen.php | 27 +++++++++++++++++++++ 5 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 module/account/config/form.php create mode 100644 module/account/test/model/create.php create mode 100644 module/account/zen.php diff --git a/module/account/config/form.php b/module/account/config/form.php new file mode 100644 index 0000000000..142fe7b326 --- /dev/null +++ b/module/account/config/form.php @@ -0,0 +1,13 @@ +account->form = new stdclass(); +$config->account->form->create = array(); +$config->account->form->create['name'] = array('type' => 'string', 'required' => true, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['provider'] = array('type' => 'string', 'required' => true, 'default' => ''); +$config->account->form->create['adminURI'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['account'] = array('type' => 'string', 'required' => true, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['password'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['email'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['mobile'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['type'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['status'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); +$config->account->form->create['extra'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); diff --git a/module/account/control.php b/module/account/control.php index 17566c67b7..6c96b08c01 100644 --- a/module/account/control.php +++ b/module/account/control.php @@ -61,21 +61,18 @@ class account extends control { if($_POST) { - $id = $this->account->create(); + $account = $this->accountZen->buildDataForCreate(); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - $this->loadModel('action')->create('account', $id, 'created'); + $this->account->create($account); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true)); - return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'callback' => 'loadCurrentPage()', 'closeModal' => true)); + if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true)); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => helper::createLink('account', 'browse'))); } $this->app->loadLang('serverroom'); - - $this->view->title = $this->lang->account->create; - $this->view->position[] = html::a($this->createLink('account', 'browse'), $this->lang->account->common); - $this->view->position[] = $this->lang->account->create; - + $this->view->title = $this->lang->account->create; $this->display(); } diff --git a/module/account/model.php b/module/account/model.php index 0c95d7738d..9a0ebe5b1c 100644 --- a/module/account/model.php +++ b/module/account/model.php @@ -88,22 +88,25 @@ class accountModel extends model return $this->dao->select('id,name')->from(TABLE_ACCOUNT)->where('deleted')->eq('0')->fetchPairs(); } - public function create() + /** + * Create account + * + * @param object $account + * @access public + * @return int|false + */ + public function create(object $account): int|false { - $account = fixer::input('post') - ->setDefault('createdBy', $this->app->user->account) - ->setDefault('createdDate', helper::now()) - ->get(); - - $this->dao->insert(TABLE_ACCOUNT) - ->data($account) + $this->dao->insert(TABLE_ACCOUNT)->data($account) ->batchCheck($this->config->account->create->requiredFields, 'notempty') ->checkIf($account->email, 'email', 'email') ->checkIf($account->mobile, 'mobile', 'mobile') ->exec(); - if(dao::isError()) return false; - return $this->dao->lastInsertID(); + + $accountID = $this->dao->lastInsertID(); + $this->loadModel('action')->create('account', $accountID, 'created'); + return $accountID; } /** diff --git a/module/account/test/model/create.php b/module/account/test/model/create.php new file mode 100644 index 0000000000..470f5d589a --- /dev/null +++ b/module/account/test/model/create.php @@ -0,0 +1,35 @@ +#!/usr/bin/env php +gen(0); + +/** + +title=accountModel->create(); +timeout=0 +cid=1 + +*/ + +$account = new stdclass(); +$account->name = '测试账号'; +$account->provider = 'aliyun'; +$account->adminURI = ''; +$account->account = 'admin'; +$account->password = 'admin'; +$account->email = 'admin@163.com'; +$account->mobile = ''; +$account->type = ''; +$account->status = ''; +$account->extra = ''; +$account->createdBy = 'admin'; +$account->createdDate = date('Y-m-d H:i:s'); + +global $tester; +$accountModel = $tester->loadModel('account'); +$accountID = $accountModel->create($account); +$account = $accountModel->getByID($accountID); +r($account) && p('name,provider,account,password') && e('测试账号,aliyun,admin,admin'); // 检查插入数据库的数据。 diff --git a/module/account/zen.php b/module/account/zen.php new file mode 100644 index 0000000000..bc3612adc8 --- /dev/null +++ b/module/account/zen.php @@ -0,0 +1,27 @@ + + * @package account + * @link https://www.zentao.net + */ +class accountZen extends account +{ + /** + * Build account data for create method. + * + * @access protected + * @return object + */ + protected function buildDataForCreate(): object + { + return form::data()->setDefault('createdBy', $this->app->user->account) + ->setDefault('createdDate', helper::now()) + ->get(); + } +} + From ae0f931d4296ab2d7ac407a1f8b2a55d9d09e190 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 08:57:44 +0800 Subject: [PATCH 173/235] * Modify language item when no stories to link. --- module/task/lang/zh-cn.php | 2 +- module/task/ui/create.html.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index b3e0241556..df215c1626 100755 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -260,7 +260,7 @@ $lang->task->confirmFinish = '"预计剩余"为0,确认将任务 $lang->task->confirmRecord = '"剩余"为0,任务将标记为"已完成",您确定吗?'; $lang->task->confirmTransfer = '剩余工时为0,当前成员已完成任务,任务指派给:%s。'; $lang->task->noticeTaskStart = '"总计消耗"和"预计剩余"不能同时为0'; -$lang->task->noticeLinkStory = "没有可关联的相关{$lang->SRCommon},您可以为当前{$lang->projectCommon}"; +$lang->task->noticeLinkStory = "没有可关联的相关{$lang->SRCommon},您可以为当前{$lang->executionCommon}"; $lang->task->noticeLinkStoryNoProduct = "没有可关联的相关{$lang->SRCommon}"; $lang->task->noticeSaveRecord = '您有尚未保存的工时记录,请先将其保存。'; $lang->task->noticeManageTeam = '任务状态是%s,不能维护团队'; diff --git a/module/task/ui/create.html.php b/module/task/ui/create.html.php index 0b06b42a34..fb639312b7 100644 --- a/module/task/ui/create.html.php +++ b/module/task/ui/create.html.php @@ -114,7 +114,7 @@ else $storyEmptyPreTip = span ( setClass('input-control-prefix'), - span($lang->task->noticeLinkStory) + span($lang->task->noticeLinkStoryNoProduct) ); } $storyPreviewBtn = span From 6fae5dafa6e86e48679a363cd6b12d0c1b698506 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 08:58:44 +0800 Subject: [PATCH 174/235] * Sync devops menu anc priv. --- module/admin/lang/menu.php | 42 +++++++++++++++++++++++---------- module/common/lang/menu.php | 20 ++++++++++++---- module/group/packagemanager.php | 27 +++++++++++++++++---- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/module/admin/lang/menu.php b/module/admin/lang/menu.php index b4f4227b66..41216bed64 100644 --- a/module/admin/lang/menu.php +++ b/module/admin/lang/menu.php @@ -187,26 +187,41 @@ $lang->admin->menuList->dev['menuOrder']['25'] = 'entry'; if(helper::hasFeature('devops')) { //$lang->admin->menuList->platform['subMenu']['environment'] = array('link' => "{$lang->devops->environment}|gitlab|browse|", 'subModule' => 'gitlab,jenkins,sonarqube,gitea,gogs', 'alias' => 'create,edit,import'); - $lang->admin->menuList->platform['subMenu']['resource'] = array('link' => "{$lang->devops->resource}|host|browse|", 'subModule' => 'host,account,serverroom,ops,tree'); + $lang->admin->menuList->platform['subMenu']['resource'] = array('link' => "{$lang->devops->resource}|host|browse|", 'subModule' => 'host,account,serverroom,ops,tree,domain,service'); $lang->admin->menuList->platform['subMenu']['setrules'] = array('link' => "{$lang->devops->rules}|repo|setrules|"); - $lang->admin->menuList->platform['tabMenu']['resource']['host'] = array('link' => "{$lang->devops->host}|host|browse|", 'alias' => 'create,edit,view,treemap,changestatus,group', 'subModule' => 'tree'); - $lang->admin->menuList->platform['tabMenu']['resource']['serverroom'] = array('link' => "{$lang->devops->serverroom}|serverroom|browse|", 'alias' => 'create,edit,view'); - $lang->admin->menuList->platform['tabMenu']['resource']['account'] = array('link' => "{$lang->devops->account}|account|browse|", 'alias' => 'create,edit,view'); + $lang->admin->menuList->platform['tabMenu']['resource']['host'] = array('link' => "{$lang->devops->host}|host|browse|", 'alias' => 'create,edit,browse,view,treemap,changestatus,group', 'subModule' => 'tree'); + $lang->admin->menuList->platform['tabMenu']['resource']['serverroom'] = array('link' => "{$lang->devops->serverroom}|serverroom|browse|", 'alias' => 'create,edit,view,browse'); + $lang->admin->menuList->platform['tabMenu']['resource']['service'] = array('link' => "{$lang->devops->service}|service|browse|", 'alias' => 'create,edit,view,browse,manage'); + $lang->admin->menuList->platform['tabMenu']['resource']['account'] = array('link' => "{$lang->devops->account}|account|browse|", 'alias' => 'create,edit,view,browse'); + $lang->admin->menuList->platform['tabMenu']['resource']['domain'] = array('link' => "{$lang->devops->domain}|domain|browse|", 'alias' => 'create,edit,view,browse'); $lang->admin->menuList->platform['tabMenu']['resource']['provider'] = array('link' => "{$lang->devops->provider}|ops|provider|", 'alias' => 'provider'); $lang->admin->menuList->platform['tabMenu']['resource']['city'] = array('link' => "{$lang->devops->city}|ops|city|", 'alias' => 'city'); $lang->admin->menuList->platform['tabMenu']['resource']['cpuBrand'] = array('link' => "{$lang->devops->cpuBrand}|ops|cpuBrand|", 'alias' => 'cpubrand'); $lang->admin->menuList->platform['tabMenu']['resource']['os'] = array('link' => "{$lang->devops->os}|ops|os|", 'alias' => 'os'); + $lang->admin->menuList->platform['tabMenu']['resource']['stage'] = array('link' => "{$lang->devops->stage}|ops|stage|", 'alias' => 'stage'); - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['5'] = 'host'; - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['10'] = 'serverroom'; - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['15'] = 'account'; - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['20'] = 'provider'; - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['25'] = 'city'; - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['30'] = 'cpuBrand'; - $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['35'] = 'os'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['10'] = 'host'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['15'] = 'serverroom'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['20'] = 'service'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['25'] = 'account'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['30'] = 'domain'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['35'] = 'provider'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['40'] = 'city'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['45'] = 'cpuBrand'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['50'] = 'os'; + $lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['55'] = 'stage'; + + if($config->edition === 'open') + { + unset($lang->admin->menuList->platform['tabMenu']['resource']['domain']); + unset($lang->admin->menuList->platform['tabMenu']['resource']['service']); + unset($lang->admin->menuList->platform['tabMenu']['resource']['stage']); + unset($lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['20']); + unset($lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['30']); + unset($lang->admin->menuList->platform['tabMenu']['menuOrder']['resource']['55']); + } - //$lang->admin->menuList->platform['menuOrder']['5'] = 'dashboard'; //$lang->admin->menuList->platform['menuOrder']['15'] = 'environment'; $lang->admin->menuList->platform['menuOrder']['20'] = 'resource'; $lang->admin->menuList->platform['menuOrder']['25'] = 'setrules'; @@ -280,7 +295,8 @@ if($config->vision == 'lite') if($config->inQuickon && helper::hasFeature('devops')) { - $lang->admin->menuList->platform['subMenu']['dashboard'] = array('link' => "{$lang->dashboard}|system|dashboard|"); + $dashboard = is_object($lang->dashboard) ? $lang->dashboard->common : $lang->dashboard; + $lang->admin->menuList->platform['subMenu']['dashboard'] = array('link' => "{$dashboard}|system|dashboard|"); $lang->admin->menuList->platform['menuOrder']['5'] = 'dashboard'; $lang->admin->menuList->system['subMenu']['backup'] = array('link' => "{$lang->backup->common}|system|browsebackup|", 'alias' => 'restorebackup'); diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index 30d9ba60b6..9479d7c48c 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -352,7 +352,7 @@ if($config->edition != 'open') $lang->execution->menu->view = array('link' => "$ $lang->execution->menu->storyGroup = array('link' => "{$lang->common->story}|execution|story|executionID=%s",'class' => 'dropdown dropdown-hover', 'subModule' => 'story', 'alias' => 'batchcreate,storykanban,batchtotask'); $lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'storykanban,linkstory,batchtotask'); $lang->execution->menu->qa = array('link' => "{$lang->qa->common}|execution|bug|executionID=%s", 'subModule' => 'bug,testcase,testtask,testreport', 'alias' => 'qa,bug,testcase,testtask,testreport'); -$lang->execution->menu->devops = array('link' => "{$lang->devops->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo,mr'); +$lang->execution->menu->devops = array('link' => "{$lang->devops->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo,mr', 'alias' => 'create'); $lang->execution->menu->doc = array('link' => "{$lang->doc->common}|execution|doc|objectID=%s", 'subModule' => 'doc'); $lang->execution->menu->build = array('link' => "{$lang->build->common}|execution|build|executionID=%s", 'subModule' => 'build'); $lang->execution->menu->action = array('link' => "$lang->dynamic|execution|dynamic|executionID=%s"); @@ -464,6 +464,7 @@ $lang->qa->menu->testsuite = array('link' => "{$lang->testcase->testsuite}|t $lang->qa->menu->testtask = array('link' => "{$lang->testtask->common}|testtask|browse|productID=%s", 'subModule' => 'testtask', 'alias' => 'view,edit,linkcase,cases,start,close,batchrun,groupcase,report,importunitresult', 'exclude' => 'testtask-browseunits'); $lang->qa->menu->report = array('link' => "{$lang->testreport->common}|testreport|browse|productID=%s", 'subModule' => 'testreport'); $lang->qa->menu->caselib = array('link' => "{$lang->testcase->caselib}|caselib|browse|libID=0", 'subModule' => 'caselib'); +$lang->qa->menu->automation = array('link' => "{$lang->automation->common}:|project|other|productID=%s", 'subModule' => 'automation', 'alias' => '', 'class' => "qa-automation-menu"); $lang->qa->menu->zahost = array('link' => "{$lang->zahost->common}|zahost|browse", 'subModule' => 'zahost'); $lang->qa->menu->zanode = array('link' => "{$lang->zanode->common}|zanode|browse", 'subModule' => 'zanode'); @@ -476,6 +477,7 @@ $lang->qa->menuOrder[25] = 'testsuite'; $lang->qa->menuOrder[30] = 'testtask'; $lang->qa->menuOrder[35] = 'report'; $lang->qa->menuOrder[40] = 'caselib'; +$lang->qa->menuOrder[45] = 'automation'; // $lang->qa->menu->automation['subMenu'] = new stdclass(); // $lang->qa->menu->automation['subMenu']->browse = array('link' => "{$lang->automation->common}|zahost|browse", 'alias' => 'create'); @@ -492,7 +494,11 @@ $lang->devops->homeMenu = new stdclass(); $lang->devops->homeMenu->repos = array('link' => "{$lang->devops->repo}|repo|maintain", 'alias' => 'create,edit,import,createrepo'); $lang->devops->homeMenu->compile = array('link' => "{$lang->devops->compile}|job|browse", 'subModule' => 'compile,job'); $lang->devops->homeMenu->artifactrepo = array('link' => "{$lang->devops->artifactrepo}|artifactrepo|browse", 'alias' => 'create'); -$lang->devops->homeMenu->apps = array('link' => "{$lang->app->common}|space|browse", 'subModule' => 'instance,store,gitlab,gitea,gogs,sonarqube', 'alias' => 'createapplication,binduser,edit'); + +if($config->edition != 'open') $lang->devops->homeMenu->deploy = array('link' => "{$lang->devops->deploy}|deploy|browse", 'alias' => 'steps,managestep,create,edit,browse,view,scope,cases', 'subModule' => 'ops,deploy'); + +$lang->devops->homeMenu->apps = array('link' => "{$lang->app->common}|space|browse", 'subModule' => 'instance,store,gitlab,gitea,gogs,jenkins,sonarqube', 'alias' => 'createapplication,binduser,edit'); + //$lang->devops->homeMenu->environment = array('link' => "{$lang->devops->environment}|gitlab|browse", 'subModule' => 'gitlab,jenkins,sonarqube,gitea,gogs', 'alias' => 'setrules,create,edit,import'); //$lang->devops->homeMenu->app = array('link' => "{$lang->app->common}|app|serverlink|%s"); @@ -501,14 +507,14 @@ $lang->devops->menu->code = array('link' => "{$lang->repo->common}|repo|brows $lang->devops->menu->mr = array('link' => "{$lang->devops->mr}|mr|browse|repoID=%s"); $lang->devops->menu->compile = array('link' => "{$lang->devops->compile}|job|browse|repoID=%s", 'subModule' => 'compile,job'); -$lang->devops->menuOrder[5] = 'dashboard'; +//$lang->devops->menuOrder[5] = 'dashboard'; $lang->devops->menuOrder[10] = 'repos'; $lang->devops->menuOrder[15] = 'code'; $lang->devops->menuOrder[20] = 'mr'; $lang->devops->menuOrder[25] = 'compile'; $lang->devops->menuOrder[30] = 'apps'; -$lang->devops->menuOrder[35] = 'environment'; -$lang->devops->menuOrder[40] = 'app'; +//$lang->devops->menuOrder[35] = 'environment'; +//$lang->devops->menuOrder[40] = 'app'; $lang->devops->dividerMenu = ',apps,'; @@ -682,6 +688,7 @@ $lang->navGroup->caselib = 'qa'; $lang->navGroup->devops = 'devops'; $lang->navGroup->repo = 'devops'; +$lang->navGroup->repo_setRules = 'admin'; $lang->navGroup->job = 'devops'; $lang->navGroup->jenkins = 'devops'; $lang->navGroup->mr = 'devops'; @@ -700,6 +707,7 @@ $lang->navGroup->devopssetting = 'devops'; $lang->navGroup->space = 'devops'; $lang->navGroup->store = 'devops'; $lang->navGroup->instance = 'devops'; +$lang->navGroup->deploy = 'devops'; $lang->navGroup->artifactrepo = 'devops'; $lang->navGroup->company = 'system'; @@ -750,6 +758,8 @@ $lang->navGroup->serverroom = 'admin'; $lang->navGroup->account = 'admin'; $lang->navGroup->host = 'admin'; $lang->navGroup->ops = 'admin'; +$lang->navGroup->service = 'admin'; +$lang->navGroup->domain = 'admin'; $lang->navGroup->index = 'index'; $lang->navGroup->misc = 'misc'; diff --git a/module/group/packagemanager.php b/module/group/packagemanager.php index 69e8be5594..bc9ab5510d 100644 --- a/module/group/packagemanager.php +++ b/module/group/packagemanager.php @@ -2520,6 +2520,10 @@ $config->group->package->workflow->privs['workflow-setApproval'] = array('editio $config->group->package->workflow->privs['workflow-setJS'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 80, 'depend' => array('workflow-browseFlow'), 'recommend' => array()); $config->group->package->workflow->privs['workflow-setCSS'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 85, 'depend' => array('workflow-browseFlow'), 'recommend' => array()); +$config->group->package->downloadCode = new stdclass(); +$config->group->package->downloadCode->order = 10; +$config->group->package->downloadCode->subset = 'repocode'; + $config->group->package->dev = new stdclass(); $config->group->package->dev->order = 5; $config->group->package->dev->subset = 'dev'; @@ -2657,6 +2661,10 @@ $config->group->package->webhook->privs['webhook-log'] = array('edition' $config->group->package->webhook->privs['webhook-bind'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'lite,rnd,or', 'order' => 30, 'depend' => array('webhook-chooseDept'), 'recommend' => array()); $config->group->package->webhook->privs['webhook-chooseDept'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'lite,rnd,or', 'order' => 35, 'depend' => array('webhook-browse'), 'recommend' => array('webhook-create', 'webhook-delete', 'webhook-edit')); +$config->group->package->gitlab = new stdclass(); +$config->group->package->gitlab->order = 10; +$config->group->package->gitlab->subset = 'repo'; + $config->group->package->sms = new stdclass(); $config->group->package->sms->order = 20; $config->group->package->sms->subset = 'notifysetting'; @@ -2766,6 +2774,10 @@ $config->group->package->chat->privs['client-create'] = array('edition' $config->group->package->chat->privs['client-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 6, 'depend' => array('admin-xuanxuan'), 'recommend' => array()); $config->group->package->chat->privs['client-delete'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 7, 'depend' => array('admin-xuanxuan'), 'recommend' => array()); +$config->group->package->jenkins = new stdclass(); +$config->group->package->jenkins->order = 25; +$config->group->package->jenkins->subset = 'repo'; + $config->group->package->systemSetting = new stdclass(); $config->group->package->systemSetting->order = 5; $config->group->package->systemSetting->subset = 'systemsetting'; @@ -2944,6 +2956,7 @@ $config->group->package->reviewcl->privs['reviewcl-view'] = $config->group->package->reviewcl->privs['reviewcl-waterfallplusBrowse'] = array('edition' => 'max,ipd', 'vision' => 'rnd', 'order' => 1, 'depend' => array(), 'recommend' => array()); $config->group->package->reviewcl->privs['reviewsetting-version'] = array('edition' => 'max,ipd', 'vision' => 'rnd', 'order' => 2, 'depend' => array(), 'recommend' => array()); $config->group->package->reviewcl->privs['reviewsetting-waterfallplusVersion'] = array('edition' => 'max,ipd', 'vision' => 'rnd', 'order' => 3, 'depend' => array(), 'recommend' => array()); +$config->group->package->reviewcl->privs['reviewcl-setCategory'] = array('edition' => 'max,ipd', 'vision' => 'rnd', 'order' => 4, 'depend' => array(), 'recommend' => array()); $config->group->package->process = new stdclass(); $config->group->package->process->order = 25; @@ -3784,6 +3797,10 @@ $config->group->package->deletePrompt->subset = 'ai'; $config->group->package->deletePrompt->privs = array(); $config->group->package->deletePrompt->privs['ai-promptDelete'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 30, 'depend' => array('admin-index', 'ai-prompts', 'ai-promptView'), 'recommend' => array()); +$config->group->package->resource = new stdclass(); +$config->group->package->resource->order = 2200; +$config->group->package->resource->subset = 'ops'; + $config->group->package->manageServiceProvider = new stdclass(); $config->group->package->manageServiceProvider->order = 2300; $config->group->package->manageServiceProvider->subset = 'ops'; @@ -3825,12 +3842,12 @@ $config->group->package->manageRepo = new stdclass(); $config->group->package->manageRepo->order = 2440; $config->group->package->manageRepo->subset = 'repo'; $config->group->package->manageRepo->privs = array(); -$config->group->package->manageRepo->privs['repo-create'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array('repo-maintain'), 'recommend' => array('repo-edit', 'repo-import')); $config->group->package->manageRepo->privs['repo-createRepo'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array('repo-maintain'), 'recommend' => array('repo-edit', 'repo-import')); -$config->group->package->manageRepo->privs['repo-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 10, 'depend' => array('repo-maintain'), 'recommend' => array('repo-create')); -$config->group->package->manageRepo->privs['repo-apiGetRepoByUrl'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 15, 'depend' => array('repo-maintain'), 'recommend' => array()); -$config->group->package->manageRepo->privs['repo-import'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 20, 'depend' => array('repo-maintain'), 'recommend' => array('repo-create')); -$config->group->package->manageRepo->privs['repo-createBranch'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 25, 'depend' => array('repo-maintain'), 'recommend' => array()); +$config->group->package->manageRepo->privs['repo-create'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 10, 'depend' => array('repo-maintain'), 'recommend' => array('repo-edit', 'repo-import')); +$config->group->package->manageRepo->privs['repo-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 15, 'depend' => array('repo-maintain'), 'recommend' => array('repo-create')); +$config->group->package->manageRepo->privs['repo-apiGetRepoByUrl'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 20, 'depend' => array('repo-maintain'), 'recommend' => array()); +$config->group->package->manageRepo->privs['repo-import'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 25, 'depend' => array('repo-maintain'), 'recommend' => array('repo-create')); +//$config->group->package->manageRepo->privs['repo-createBranch'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 25, 'depend' => array('repo-maintain'), 'recommend' => array()); $config->group->package->deleteRepo = new stdclass(); $config->group->package->deleteRepo->order = 2500; From 85202eae91874fc3351fd587a9e44a545b32aa54 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 09:03:45 +0800 Subject: [PATCH 175/235] * Hide the story section if there is no story to link. --- module/task/js/create.ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/task/js/create.ui.js b/module/task/js/create.ui.js index 706cfa3e64..4318f10558 100644 --- a/module/task/js/create.ui.js +++ b/module/task/js/create.ui.js @@ -201,7 +201,7 @@ window.loadExecutionStories = function() setPreview(); /* If there is no story option, select will be hidden and text will be displayed; otherwise, the opposite is true */ - if(stories.length || parseInt(hasProduct) == 0) + if(stories.length) { $('#story').closest('.form-group').removeClass('hidden'); $('.empty-story-tip').closest('.form-group').addClass('hidden'); From 9b54ed236e6b84466e1bffe3048e71fe9aa278dc Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 09:16:39 +0800 Subject: [PATCH 176/235] * Hide priview btn when the story isn't selected. --- module/task/js/create.ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/task/js/create.ui.js b/module/task/js/create.ui.js index 4318f10558..b45e5318be 100644 --- a/module/task/js/create.ui.js +++ b/module/task/js/create.ui.js @@ -285,7 +285,7 @@ function setStoryRelated() */ function setPreview() { - if(!$("input[name='story']").val()) + if(parseFloat($("input[name='story']").val()) == 0) { $('#preview').addClass('hidden'); $('.title-group.required > div').removeAttr('id', 'copyStory-input').addClass('.required'); From e9f79553ce9c50dc69016b69993372145ca86b06 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 09:21:06 +0800 Subject: [PATCH 177/235] * Update language. --- module/common/lang/de.php | 8 +++++++- module/common/lang/en.php | 7 ++++++- module/common/lang/fr.php | 8 +++++++- module/common/lang/zh-cn.php | 4 +++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/module/common/lang/de.php b/module/common/lang/de.php index ac70cfc2b8..bfef63995c 100644 --- a/module/common/lang/de.php +++ b/module/common/lang/de.php @@ -190,7 +190,7 @@ $lang->kanban->common = 'Kanban'; $lang->qa->common = 'QA'; $lang->devops->common = 'DevOps'; $lang->doc->common = 'Doc'; -$lang->repo->common = 'Code'; +$lang->repo->common = 'Code Repo'; $lang->repo->codeRepo = 'Code Repo'; $lang->bi->common = 'BI'; $lang->screen->common = 'Screen'; @@ -277,6 +277,8 @@ $lang->projectreview->common = 'Review'; $lang->projecttrack->common = 'Matrix'; $lang->projectqa->common = 'QA'; $lang->holidayseason->common = 'Holiday'; +$lang->codereview->common = 'Review'; +$lang->repocode->common = 'Code'; $lang->personnel->common = 'Member'; $lang->personnel->invest = 'Investment'; @@ -380,6 +382,7 @@ $lang->devops->mr = 'Merge Request'; $lang->devops->repo = 'Repo'; $lang->devops->rules = 'Rule'; $lang->devops->settings = 'Setting Merge Request'; +$lang->devops->platform = 'Platform'; $lang->devops->set = 'Set'; $lang->devops->artifactrepo = 'Artifact Repo'; $lang->devops->environment = 'Environment'; @@ -390,10 +393,13 @@ $lang->devops->oss = 'Oss'; $lang->devops->host = 'Host'; $lang->devops->account = 'Account'; $lang->devops->serverroom = 'IDC'; +$lang->devops->deploy = 'Deploy'; $lang->devops->provider = 'IDC Provider'; $lang->devops->cpuBrand = 'CPU Brand'; $lang->devops->city = 'IDC Location'; $lang->devops->os = 'OS Version'; +$lang->devops->stage = 'Stage'; +$lang->devops->service = 'Service'; $lang->admin->module = 'Module'; $lang->admin->system = 'System'; diff --git a/module/common/lang/en.php b/module/common/lang/en.php index f8b339a70b..93db30d710 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -191,7 +191,7 @@ $lang->kanban->common = 'Kanban'; $lang->qa->common = 'QA'; $lang->devops->common = 'DevOps'; $lang->doc->common = 'Doc'; -$lang->repo->common = 'Code'; +$lang->repo->common = 'Code Repo'; $lang->repo->codeRepo = 'Code Repo'; $lang->bi->common = 'BI'; $lang->screen->common = 'Screen'; @@ -278,6 +278,8 @@ $lang->projectreview->common = 'Review'; $lang->projecttrack->common = 'Matrix'; $lang->projectqa->common = 'QA'; $lang->holidayseason->common = 'Holiday'; +$lang->codereview->common = 'Review'; +$lang->repocode->common = 'Code'; $lang->personnel->common = 'Member'; $lang->personnel->invest = 'Investment'; @@ -392,10 +394,13 @@ $lang->devops->oss = 'Oss'; $lang->devops->host = 'Host'; $lang->devops->account = 'Account'; $lang->devops->serverroom = 'IDC'; +$lang->devops->deploy = 'Deploy'; $lang->devops->provider = 'IDC Provider'; $lang->devops->cpuBrand = 'CPU Brand'; $lang->devops->city = 'IDC Location'; $lang->devops->os = 'OS Version'; +$lang->devops->stage = 'Stage'; +$lang->devops->service = 'Service'; $lang->admin->module = 'Module'; $lang->admin->system = 'System'; diff --git a/module/common/lang/fr.php b/module/common/lang/fr.php index 8961965a1e..fe3eac229b 100644 --- a/module/common/lang/fr.php +++ b/module/common/lang/fr.php @@ -190,7 +190,7 @@ $lang->kanban->common = 'Kanban'; $lang->qa->common = 'QA'; $lang->devops->common = 'DevOps'; $lang->doc->common = 'Doc'; -$lang->repo->common = 'Code'; +$lang->repo->common = 'Code Repo'; $lang->repo->codeRepo = 'Code Repo'; $lang->bi->common = 'BI'; $lang->screen->common = 'Screen'; @@ -277,6 +277,8 @@ $lang->projectreview->common = 'Review'; $lang->projecttrack->common = 'Matrix'; $lang->projectqa->common = 'QA'; $lang->holidayseason->common = 'Holiday'; +$lang->codereview->common = 'Review'; +$lang->repocode->common = 'Code'; $lang->personnel->common = 'Member'; $lang->personnel->invest = 'Investment'; @@ -380,6 +382,7 @@ $lang->devops->mr = 'Merge Request'; $lang->devops->repo = 'Repo'; $lang->devops->rules = 'Rule'; $lang->devops->settings = 'Setting Merge Request'; +$lang->devops->platform = 'Platform'; $lang->devops->set = 'Set'; $lang->devops->artifactrepo = 'Artifact Repo'; $lang->devops->environment = 'Environment'; @@ -390,10 +393,13 @@ $lang->devops->oss = 'Oss'; $lang->devops->host = 'Host'; $lang->devops->account = 'Account'; $lang->devops->serverroom = 'IDC'; +$lang->devops->deploy = 'Deploy'; $lang->devops->provider = 'IDC Provider'; $lang->devops->cpuBrand = 'CPU Brand'; $lang->devops->city = 'IDC Location'; $lang->devops->os = 'OS Version'; +$lang->devops->stage = 'Stage'; +$lang->devops->service = 'Service'; $lang->admin->module = 'Module'; $lang->admin->system = 'System'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 0d33742f51..568be79dfe 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -191,7 +191,7 @@ $lang->kanban->common = '看板'; $lang->qa->common = '测试'; $lang->devops->common = 'DevOps'; $lang->doc->common = '文档'; -$lang->repo->common = '代码'; +$lang->repo->common = '代码库'; $lang->repo->codeRepo = '代码库'; $lang->bi->common = 'BI'; $lang->screen->common = '大屏'; @@ -278,6 +278,8 @@ $lang->projectreview->common = '评审'; $lang->projecttrack->common = '矩阵'; $lang->projectqa->common = '测试'; $lang->holidayseason->common = '节假日'; +$lang->codereview->common = '问题'; +$lang->repocode->common = '代码'; $lang->personnel->common = '人员'; $lang->personnel->invest = '投入人员'; From 2fe32e176197b9afb126e4903fc8cd0aef7daed2 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 09:23:11 +0800 Subject: [PATCH 178/235] * Update language. --- module/common/lang/zh-cn.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 568be79dfe..aa3c44cc23 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -394,10 +394,13 @@ $lang->devops->oss = '对象存储'; $lang->devops->host = '主机'; $lang->devops->account = '账号'; $lang->devops->serverroom = '机房'; +$lang->devops->deploy = '上线'; $lang->devops->provider = '服务商'; $lang->devops->cpuBrand = 'CPU品牌'; $lang->devops->city = '城市'; $lang->devops->os = '系统版本'; +$lang->devops->stage = '阶段'; +$lang->devops->service = '服务'; $lang->admin->module = '功能配置'; $lang->admin->system = '系统'; From afeb2c13fe297cd240e5e0172d2136c4da988b00 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Mon, 20 Nov 2023 09:28:53 +0800 Subject: [PATCH 179/235] * Fix count_of_assigned_bug_in_user. --- .../metric/calc/user/scale/count_of_assigned_bug_in_user.php | 2 +- module/metric/zen.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php b/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php index 9f846b028b..f3c0926354 100755 --- a/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_bug_in_user.php @@ -20,7 +20,7 @@ */ class count_of_assigned_bug_in_user extends baseCalc { - public $dataset = 'getProjectBugs'; + public $dataset = 'getBugs'; public $fieldList = array('t1.assignedTo'); diff --git a/module/metric/zen.php b/module/metric/zen.php index 084e8d3dc2..27daa768c5 100644 --- a/module/metric/zen.php +++ b/module/metric/zen.php @@ -247,7 +247,9 @@ class metricZen extends metric { if(strpos(strtoupper($field), ' AS ') !== false) { - $extractField = explode(' AS ', $field); + $pos = strpos(strtoupper($field), ' AS '); + $tag = substr($field, $pos, 4); + $extractField = explode($tag, $field); $pureField = end($extractField); $aliasField = $pureField; } From 06c688627ef0cbec7b583a4e1d282cb90a4527d2 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 09:32:54 +0800 Subject: [PATCH 180/235] * Init language. --- module/common/lang/common.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/module/common/lang/common.php b/module/common/lang/common.php index d9f4b6544c..989833aab0 100644 --- a/module/common/lang/common.php +++ b/module/common/lang/common.php @@ -102,6 +102,9 @@ $lang->instance = new stdclass(); $lang->CNE = new stdclass(); $lang->account = new stdclass(); $lang->ops = new stdclass(); +$lang->domain = new stdclass(); +$lang->service = new stdclass(); +$lang->deploy = new stdclass(); $lang->metric = new stdclass(); $lang->serverroom = new stdclass(); @@ -147,6 +150,9 @@ $lang->projectreview = new stdclass(); $lang->projecttrack = new stdclass(); $lang->projectqa = new stdclass(); $lang->holidayseason = new stdclass(); +$lang->codereview = new stdclass(); +$lang->repocode = new stdclass(); +$lang->deploy = new stdclass(); $lang->projectbuild = new stdclass(); $lang->projectrelease = new stdclass(); @@ -215,6 +221,7 @@ $lang->icons['close'] = 'off'; $lang->icons['activate'] = 'magic'; $lang->icons['review'] = 'glasses'; $lang->icons['confirm'] = 'search'; +$lang->icons['confirmBug'] = 'search'; $lang->icons['putoff'] = 'calendar'; $lang->icons['suspend'] = 'pause'; $lang->icons['pause'] = 'pause'; From 7c1aa13d9de57e4435424c7752ae08a0fb52fdf7 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 09:34:12 +0800 Subject: [PATCH 181/235] * Refactor linkBug with searchForm. --- module/release/ui/linkbug.html.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/module/release/ui/linkbug.html.php b/module/release/ui/linkbug.html.php index d1801dabbf..6e974d738f 100644 --- a/module/release/ui/linkbug.html.php +++ b/module/release/ui/linkbug.html.php @@ -16,7 +16,13 @@ $cols = array(); foreach($config->release->dtable->defaultFields['linkBug'] as $field) $cols[$field] = zget($config->bug->dtable->fieldList, $field, array()); $cols = array_map(function($col){$col['show'] = true; return $col;}, $cols); -div(setID("{$type}SearchFormPanel"), set('data-module', 'bug'), searchToggle(set::open(true), set::module('bug'), set::formName("{$type}SearchFormPanel"))); +searchForm +( + set::module('bug'), + set::simple(true), + set::show(true) +); + dtable ( set::id('unlinkBugList'), From 5daf4d4ac3f215d12df04412bb471e906ec51207 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 09:34:44 +0800 Subject: [PATCH 182/235] * Remove the empty value from the budget picker. --- module/program/ui/create.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/program/ui/create.html.php b/module/program/ui/create.html.php index 9408bdefaf..a46886837c 100644 --- a/module/program/ui/create.html.php +++ b/module/program/ui/create.html.php @@ -70,7 +70,7 @@ formPanel set::suffix($lang->project->tenThousandYuan), set::suffixWidth(50) ), - $parentProgram ? formHidden('budgetUnit', $parentProgram->budgetUnit) : picker(set::name('budgetUnit'), set::items($budgetUnitList), set::value($config->project->defaultCurrency)) + $parentProgram ? formHidden('budgetUnit', $parentProgram->budgetUnit) : picker(set::name('budgetUnit'), set::items($budgetUnitList), set::value($config->project->defaultCurrency), set::required(true)) ) ), formGroup From b2b56895e4284dcf892de9ad2ef9e80a8b1caa49 Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 01:37:28 +0000 Subject: [PATCH 183/235] * Display PMT field when edition is ipd. --- module/product/config/formdata.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/product/config/formdata.php b/module/product/config/formdata.php index cbf7dda6a0..e403097a97 100644 --- a/module/product/config/formdata.php +++ b/module/product/config/formdata.php @@ -10,7 +10,7 @@ $config->product->form->create['PO'] = array('type' => 'account', 'c $config->product->form->create['QD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->create['RD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->create['reviewer'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'options' => 'users'); -$config->product->form->create['PMT'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'options' => 'users'); +if($this->config->edition == 'ipd') $config->product->form->create['PMT'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'options' => 'users'); $config->product->form->create['type'] = array('type' => 'string', 'control' => 'select', 'required' => false, 'default' => 'normal', 'options' => $lang->product->typeList); $config->product->form->create['status'] = array('type' => 'string', 'control' => 'hidden', 'required' => false, 'default' => 'normal'); $config->product->form->create['desc'] = array('type' => 'string', 'control' => 'editor', 'required' => false, 'default' => '', 'width' => 'full'); @@ -30,7 +30,7 @@ if(isset($this->config->setCode) && $this->config->setCode == 1) $config->produc $config->product->form->edit['PO'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->edit['QD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); $config->product->form->edit['RD'] = array('type' => 'account', 'control' => 'select', 'required' => false, 'default' => '', 'options' => array()); -$config->product->form->edit['PMT'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'options' => 'users'); +if($this->config->edition == 'ipd') $config->product->form->edit['PMT'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'options' => 'users'); $config->product->form->edit['reviewer'] = array('type' => 'array', 'control' => 'multi-select', 'required' => false, 'default' => '', 'filter' => 'join', 'options' => 'users'); $config->product->form->edit['type'] = array('type' => 'string', 'control' => 'select', 'required' => false, 'default' => 'normal', 'options' => $lang->product->typeList); $config->product->form->edit['status'] = array('type' => 'string', 'control' => 'select', 'required' => false, 'default' => 'normal', 'options' => $lang->product->statusList); From 00a153af5d8cb8a4cdc2863d1f6230f8f5d9d6fc Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 09:21:02 +0800 Subject: [PATCH 184/235] * productplan: refactor. --- module/productplan/js/view.ui.js | 2 +- module/productplan/ui/view.html.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/module/productplan/js/view.ui.js b/module/productplan/js/view.ui.js index 5e0db198a3..877d4aab17 100644 --- a/module/productplan/js/view.ui.js +++ b/module/productplan/js/view.ui.js @@ -33,7 +33,7 @@ window.showLink = function(type, params, onlyUpdateTable) const url = $.createLink('productplan', type === 'story' ? 'linkStory' : 'linkBug', 'planID=' + planID + (params || '&browseType=¶m=')); if(onlyUpdateTable) { - loadComponent($('#' + (type === 'story' ? 'stories' : 'bugs')).find('.dtable').attr('id'), {url: url, component: 'dtable'}); + loadComponent($('#' + (type === 'story' ? 'stories' : 'bugs')).find('.dtable').attr('id'), {url: url, component: 'dtable', partial: true}); return; } loadTarget({url: url, target: type === 'story' ? 'stories' : 'bugs'}); diff --git a/module/productplan/ui/view.html.php b/module/productplan/ui/view.html.php index f85c6cf822..71e1771c55 100644 --- a/module/productplan/ui/view.html.php +++ b/module/productplan/ui/view.html.php @@ -199,8 +199,6 @@ detailBody set::icon('link'), set::text($lang->productplan->linkStory), bind::click("window.showLink('story')") - // set::url(inlink('linkStory', "planID={$plan->id}" . (($link == 'true' && $type == 'story') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}")), - // setData(array('load' => 'target', 'target' => '#stories')) ) : null ), dtable @@ -243,8 +241,6 @@ detailBody set::icon('link'), set::text($lang->productplan->linkBug), bind::click("window.showLink('bug')") - // set::url(inlink('linkBug', "planID={$plan->id}" . (($link == 'true' && $type == 'bug') ? $decodeParam : "&browseType=¶m=") . "&orderBy={$orderBy}")), - // setData(array('load' => 'target', 'target' => '#bugs')) ) : null ), dtable From afc9aa58d673f53bd4659e4b46d789aa552bc616 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 09:41:39 +0800 Subject: [PATCH 185/235] * build: fix link bug and story with searchForm not work. --- module/build/js/view.ui.js | 26 ++++++++++++++++++-------- module/build/ui/linkbug.html.php | 3 ++- module/build/ui/linkstory.html.php | 3 ++- module/build/ui/view.html.php | 20 ++++++++++++++++++-- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/module/build/js/view.ui.js b/module/build/js/view.ui.js index c19d052cba..b47e217458 100644 --- a/module/build/js/view.ui.js +++ b/module/build/js/view.ui.js @@ -28,11 +28,22 @@ $(document).off('click','.dtable-footer .batch-btn').on('click', '.dtable-footer window.appendLinkBtn(); }); -window.showLink = function(obj) +window.showLink = function(type, params, onlyUpdateTable) { - var $this = $(obj); - var idName = $this.data('type') == 'story' ? '#story' : '#bug'; - $(idName).load($this.data('linkurl')); + const url = $.createLink(buildModule, type === 'story' ? 'linkStory' : 'linkBug', 'buildID=' + buildID + (params || '&browseType=¶m=')); + if(onlyUpdateTable) + { + loadComponent($('#' + type).find('.dtable').attr('id'), {url: url, component: 'dtable', partial: true}); + return; + } + loadTarget({url: url, target: type}); +}; + +window.onSearchLinks = function(type, result) +{ + const params = $.parseLink(result.load).vars[3]; + showLink(type, params ? atob(params[1]) : null, true); + return false; }; $(document).on('click', '.linkObjectBtn', function() @@ -60,8 +71,7 @@ $(document).on('click', '.linkObjectBtn', function() $.ajaxSubmit({"url": $(this).data('url'), "data": postData}); }); -if(initLink == 'true') +$(function() { - var idName = type == 'story' ? '#story' : '#bug'; - window.showLink($(idName).find('.link')); -} + if(initLink == 'true') window.showLink(type, linkParams); +}); diff --git a/module/build/ui/linkbug.html.php b/module/build/ui/linkbug.html.php index ca6651096e..d9eefbbfb6 100644 --- a/module/build/ui/linkbug.html.php +++ b/module/build/ui/linkbug.html.php @@ -32,7 +32,8 @@ searchForm ( set::module('bug'), set::simple(true), - set::show(true) + set::show(true), + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'bug')")) ); dtable diff --git a/module/build/ui/linkstory.html.php b/module/build/ui/linkstory.html.php index 568b9d45ba..80f812fb76 100644 --- a/module/build/ui/linkstory.html.php +++ b/module/build/ui/linkstory.html.php @@ -28,7 +28,8 @@ searchForm ( set::module('story'), set::simple(true), - set::show(true) + set::show(true), + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'story')")) ); dtable diff --git a/module/build/ui/view.html.php b/module/build/ui/view.html.php index a8f67bcd83..46cd7a88a4 100644 --- a/module/build/ui/view.html.php +++ b/module/build/ui/view.html.php @@ -58,10 +58,12 @@ detailHeader jsVar('initLink', $link); jsVar('type', $type); +jsVar('linkParams', $decodeParam); jsVar('buildID', $build->id); jsVar('confirmDelete', $lang->build->confirmDelete); jsVar('currentAccount', $app->user->account); jsVar('buildProduct', $build->product); +jsVar('buildModule', $buildModule); /* Story's batch btn. */ $canBatchUnlinkStory = $canBeChanged && common::hasPriv($buildModule, 'batchUnlinkStory'); @@ -118,7 +120,13 @@ detailBody div ( setClass('tab-actions'), - !common::hasPriv($buildModule, 'linkStory') ? null : btn(set::text($lang->build->linkStory), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'story'), set('data-linkurl', createLink($buildModule, 'linkStory', "buildID={$build->id}" . (($link == 'true' && $type == 'story') ? $decodeParam : "&browseType=¶m=")))) + common::hasPriv($buildModule, 'linkStory') ? btn + ( + set::text($lang->build->linkStory), + set::icon('link'), + set::type('primary'), + bind::click("window.showLink('story')") + ) : null ), dtable ( @@ -129,6 +137,7 @@ detailBody set::checkable($canBatchUnlinkStory || $canBatchCloseStory), set::sortLink(createLink($buildModule, 'view', "buildID={$build->id}&type=story&link={$link}¶m={$param}&orderBy={name}_{sortType}")), set::orderBy($orderBy), + set::extraHeight('+144'), set::footToolbar($storyFootToolbar), set::footPager(usePager('storyPager', '', array( 'recPerPage' => $storyPager->recPerPage, @@ -148,7 +157,13 @@ detailBody div ( setClass('tab-actions'), - !common::hasPriv($buildModule, 'linkBug') ? null : btn(set::text($lang->build->linkBug), setClass('primary link'), set::icon('link'), set::onclick('showLink(this)'), set('data-type', 'bug'), set('data-linkurl', createLink($buildModule, 'linkBug', "buildID={$build->id}" . (($link == 'true' && $type == 'bug') ? $decodeParam : "&browseType=¶m=")))) + common::hasPriv($buildModule, 'linkBug') ? btn + ( + set::text($lang->build->linkBug), + set::type('primary'), + set::icon('link'), + bind::click("window.showLink('bug')") + ) : null ), dtable ( @@ -159,6 +174,7 @@ detailBody set::checkable($canBatchUnlinkBug || $canBatchCloseBug), set::sortLink(createLink($buildModule, 'view', "buildID={$build->id}&type=bug&link={$link}¶m={$param}&orderBy={name}_{sortType}")), set::orderBy($orderBy), + set::extraHeight('+144'), set::footToolbar($bugFootToolbar), set::footPager(usePager('bugPager', '', array( 'recPerPage' => $bugPager->recPerPage, From 2c2b590cbc968759e9729d1604ac29b9ef9f57bb Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 09:47:15 +0800 Subject: [PATCH 186/235] * Change the to upgrade Biz edition tip. --- module/file/lang/de.php | 2 +- module/file/lang/en.php | 2 +- module/file/lang/fr.php | 2 +- module/file/lang/zh-cn.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/module/file/lang/de.php b/module/file/lang/de.php index 7dab50d4bc..eeb17e2df7 100755 --- a/module/file/lang/de.php +++ b/module/file/lang/de.php @@ -73,7 +73,7 @@ $lang->file->errorExtract = 'Entpacken fehlgeschlagen. Die Datei ist vermutl $lang->file->errorUploadEmpty = 'No upload file.'; $lang->file->fileNotFound = 'The file was not found. The physical file might have been deleted!'; $lang->file->fileContentEmpty = 'The file is empty. Check the file and upload it again.'; -$lang->file->bizGuide = 'To utilize Excel import/export, upgrade to ZenTao %s edition on our website'; +$lang->file->bizGuide = 'To utilize Excel import/export, upgrade to ZenTao %s edition'; $lang->file->uploadError[1] = 'The uploaded filesize exceeds the limit. Please change the upload_max_filesize and post_max_size options in php.ini'; $lang->file->uploadError[2] = 'The size of the uploaded file exceeds the value specified by the MAX_FILE_SIZE option in the HTML form'; diff --git a/module/file/lang/en.php b/module/file/lang/en.php index 9b74ff3007..5781112658 100755 --- a/module/file/lang/en.php +++ b/module/file/lang/en.php @@ -73,7 +73,7 @@ $lang->file->errorExtract = 'Extracting files failed. Files might be damaged $lang->file->errorUploadEmpty = 'No upload file.'; $lang->file->fileNotFound = 'The file was not found. The physical file might have been deleted!'; $lang->file->fileContentEmpty = 'The file is empty. Check the file and upload it again.'; -$lang->file->bizGuide = 'To utilize Excel import/export, upgrade to ZenTao %s edition on our website'; +$lang->file->bizGuide = 'To utilize Excel import/export, upgrade to ZenTao %s edition'; $lang->file->uploadError[1] = 'The uploaded filesize exceeds the limit. Please change the upload_max_filesize and post_max_size options in php.ini'; $lang->file->uploadError[2] = 'The size of the uploaded file exceeds the value specified by the MAX_FILE_SIZE option in the HTML form'; diff --git a/module/file/lang/fr.php b/module/file/lang/fr.php index de75cb17d0..c69a984665 100755 --- a/module/file/lang/fr.php +++ b/module/file/lang/fr.php @@ -73,7 +73,7 @@ $lang->file->errorExtract = "Echec de l'extraction des fichiers. Les fichier $lang->file->errorUploadEmpty = 'No upload file.'; $lang->file->fileNotFound = 'Fichier non trouvé. Le fichier physique a peut-être été supprimé par innadvertance !'; $lang->file->fileContentEmpty = 'The file is empty. Check the file and upload it again.'; -$lang->file->bizGuide = 'To utilize Excel import/export, upgrade to ZenTao %s edition on our website'; +$lang->file->bizGuide = 'To utilize Excel import/export, upgrade to ZenTao %s edition'; $lang->file->uploadError[1] = 'The uploaded filesize exceeds the limit. Please change the upload_max_filesize and post_max_size options in php.ini'; $lang->file->uploadError[2] = 'The size of the uploaded file exceeds the value specified by the MAX_FILE_SIZE option in the HTML form'; diff --git a/module/file/lang/zh-cn.php b/module/file/lang/zh-cn.php index 5aa4f19c6e..bdfcc398ef 100755 --- a/module/file/lang/zh-cn.php +++ b/module/file/lang/zh-cn.php @@ -73,7 +73,7 @@ $lang->file->errorExtract = '解压缩失败!可能文件已经损坏, $lang->file->errorUploadEmpty = '没有等待上传的文件'; $lang->file->fileNotFound = '未找到该文件,可能物理文件已被删除!'; $lang->file->fileContentEmpty = '上传文件内容为空,请检查后重新上传。'; -$lang->file->bizGuide = '如需使用EXCEL导入导出功能,可到官网升级到%s'; +$lang->file->bizGuide = '如需使用Excel导入导出功能,可升级到 %s'; $lang->file->uploadError[1] = "上传的文件大小超过了限制,请修改 php.ini 中 upload_max_filesize 与 post_max_size 选项限制的值"; $lang->file->uploadError[2] = '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值'; From 2174c9e1656ca398356c7cafcc76fd6348e8f728 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 09:56:53 +0800 Subject: [PATCH 187/235] * Change to new writing method. --- module/story/ui/edit.html.php | 42 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/module/story/ui/edit.html.php b/module/story/ui/edit.html.php index 846267bb8c..4b0e68c831 100644 --- a/module/story/ui/edit.html.php +++ b/module/story/ui/edit.html.php @@ -65,7 +65,7 @@ detailHeader detailBody ( - set::id('dataform'), + setID('dataform'), set::isForm(true), $canEditContent ? set::actions(array ( @@ -107,7 +107,7 @@ detailBody ( picker ( - set::id('reviewer'), + setID('reviewer'), set::name('reviewer[]'), set::items($fields['reviewer']['options']), set::value($fields['reviewer']['default']), @@ -119,7 +119,7 @@ detailBody setClass('input-group-addon'), checkbox ( - set::id('needNotReview'), + setID('needNotReview'), set::name('needNotReview'), set::checked(empty($fields['reviewer']['default'])), set::value(1), @@ -159,9 +159,9 @@ detailBody setClass('twins'), $branch ? label(setClass($labelClass . ' circle branch size-sm'), set::title($branch), $branch) : null, label(setClass('circle size-sm'), $twin->id), - common::hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "id={$twin->id}")), setClass('title'), set::title($twin->title), set('data-toggle', 'modal'), $twin->title) : span(setClass('title'), $twin->title), + common::hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "id={$twin->id}")), setClass('title'), set::title($twin->title), setData(array('toggle' => 'modal')), $twin->title) : span(setClass('title'), $twin->title), label(setClass('size-sm'), set::title($stage), $stage), - common::hasPriv('story', 'relieved') ? a(set::title($lang->story->relievedTwins), setClass("relievedTwins unlink size-xs"), on::click('unlinkTwins'), set('data-id', $twin->id), icon('unlink')) : null + common::hasPriv('story', 'relieved') ? a(set::title($lang->story->relievedTwins), setClass("relievedTwins unlink size-xs"), on::click('unlinkTwins'), setData(array('id' => $twin->id)), icon('unlink')) : null ); }, $twins)) ) @@ -197,7 +197,7 @@ detailBody ( picker ( - set::id('product'), + setID('product'), set::name('product'), set::items($fields['product']['options']), set::value($fields['product']['default']), @@ -209,7 +209,7 @@ detailBody setClass($product->type == 'normal' ? 'hidden' : ''), $product->type != 'normal' ? picker ( - set::id('branch'), + setID('branch'), set::name('branch'), set::items($fields['branch']['options']), set::value($fields['branch']['default']), @@ -230,7 +230,7 @@ detailBody ( span ( - set('id', 'moduleIdBox'), + setID('moduleIdBox'), picker ( set::name('module'), @@ -238,7 +238,7 @@ detailBody set::value($fields['module']['default']) ) ), - count($moduleOptionMenu) == 1 ? btn(set::url($this->createLink('tree', 'browse', "rootID={$story->product}&view=story¤tModuleID=0&branch={$story->branch}")), set('data-toggle', 'modal'), $lang->tree->manage) : null, + count($moduleOptionMenu) == 1 ? btn(set::url($this->createLink('tree', 'browse', "rootID={$story->product}&view=story¤tModuleID=0&branch={$story->branch}")), setData(array('toggle' => 'modal')), $lang->tree->manage) : null, count($moduleOptionMenu) == 1 ? btn(set('onclick', "loadProductModules({$story->product})"), setClass('refresh'), icon('refresh')) : null ) ), @@ -256,10 +256,10 @@ detailBody ( span ( - set::id('planIdBox'), + setID('planIdBox'), picker(setID('plan'), set::name($multiplePlan ? 'plan[]' : 'plan'), set::items($fields['plan']['options']), set::value($fields['parent']['default']), set::multiple($multiplePlan)), ), - empty($plans) ? btn(set::url($this->createLink('productplan', 'create', "productID={$story->product}&branch={$story->branch}")), set('data-toggle', 'modal'), icon('plus')) : null, + empty($plans) ? btn(set::url($this->createLink('productplan', 'create', "productID={$story->product}&branch={$story->branch}")), setData(array('toggle' => 'modal')), icon('plus')) : null, empty($plans) ? btn(set('onclick', "loadProductPlans({$story->product})"), setClass('refresh'), icon('refresh')) : null ) ), @@ -334,13 +334,13 @@ detailBody ( set('url', createLink('my', 'managecontacts', 'listID=0&mode=new')), set('title', $lang->user->contacts->manage), - set('data-toggle', 'modal'), + setData(array('toggle' => 'modal')), icon('cog') ), isset($contactList) ? null : btn ( - set('id', 'refreshMailto'), - set('class', 'text-black'), + setID('refreshMailto'), + setClass('text-black'), icon('refresh') ) ) @@ -370,7 +370,7 @@ detailBody set::name($lang->story->reviewers), picker ( - set::id('reviewer'), + setID('reviewer'), set::name('reviewer[]'), set::items($fields['reviewer']['options']), set::value($fields['reviewer']['default']), @@ -404,18 +404,16 @@ detailBody ($story->type == 'story' && common::hasPriv('story', 'linkStories')) ? btn ( setClass('secondary'), - set::id('linkStoriesLink'), - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setID('linkStoriesLink'), + setData(array('toggle' => 'modal', 'size' => 'lg')), on::click('linkStories'), $lang->story->linkStoriesAB ) : null, ($story->type == 'requirement' && common::hasPriv('requirement', 'linkRequirements')) ? btn ( setClass('secondary'), - set::id('linkStoriesLink'), - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setID('linkStoriesLink'), + setData(array('toggle' => 'modal', 'size' => 'lg')), on::click('linkStories'), $lang->story->linkRequirementsAB ) : null @@ -438,7 +436,7 @@ detailBody ); }, array_keys($story->linkStoryTitles), array_values($story->linkStoryTitles))) ) : null, - div(set::id('linkStoriesBox')) + div(setID('linkStoriesBox')) ) ) ) From c7a20ae4fc217453ef5a2e330161ed48ce5e770d Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 02:08:15 +0000 Subject: [PATCH 188/235] * Set items if it is setted options. --- module/product/ui/create.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/product/ui/create.html.php b/module/product/ui/create.html.php index a4a00adc50..188fd5e6c9 100644 --- a/module/product/ui/create.html.php +++ b/module/product/ui/create.html.php @@ -29,7 +29,7 @@ foreach($fields as $field => $attr) $fieldName .= '[]'; } - if($control['type'] == 'picker' || $control['type'] == 'radioList') $control['items'] = $attr['options']; + if(isset($attr['options'])) $control['items'] = $attr['options']; if($field == 'line' && hasPriv('product', 'manageLine') && $programID) { From 59d222939ba14e56512f01c4cabb07d9d479f22f Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 02:11:36 +0000 Subject: [PATCH 189/235] * Format codes. --- module/product/ui/activate.html.php | 3 ++- module/product/ui/close.html.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/module/product/ui/activate.html.php b/module/product/ui/activate.html.php index da3431dcb4..97cc747612 100644 --- a/module/product/ui/activate.html.php +++ b/module/product/ui/activate.html.php @@ -23,7 +23,8 @@ formPanel set::name('comment'), set::rows('6') ), - input( + input + ( set::className('hidden'), set::name('status'), set::value('normal') diff --git a/module/product/ui/close.html.php b/module/product/ui/close.html.php index adf82381f3..5f0b56574a 100644 --- a/module/product/ui/close.html.php +++ b/module/product/ui/close.html.php @@ -23,7 +23,8 @@ formPanel set::name('comment'), set::rows('6') ), - input( + input + ( set::className('hidden'), set::name('status'), set::value('closed') From 57d9bee74c6461e33dd998544f733b92c61b7fba Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 20 Nov 2023 10:18:11 +0800 Subject: [PATCH 190/235] * Rewrite account edit method. --- module/account/config/form.php | 2 + module/account/control.php | 15 ++----- module/account/model.php | 29 +++++++------ module/account/test/model/getbyid.php | 20 +++++++++ module/account/test/model/update.php | 39 +++++++++++++++++ module/account/zen.php | 17 +++++++- module/serverroom/model.php | 2 +- module/serverroom/test/model/getpairs.php | 21 ++++++++++ test/data/serverroom.yaml | 51 ++++++++++------------- 9 files changed, 139 insertions(+), 57 deletions(-) create mode 100644 module/account/test/model/getbyid.php create mode 100644 module/account/test/model/update.php create mode 100644 module/serverroom/test/model/getpairs.php diff --git a/module/account/config/form.php b/module/account/config/form.php index 142fe7b326..b9bf3d04b2 100644 --- a/module/account/config/form.php +++ b/module/account/config/form.php @@ -11,3 +11,5 @@ $config->account->form->create['mobile'] = array('type' => 'string', 'required $config->account->form->create['type'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); $config->account->form->create['status'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); $config->account->form->create['extra'] = array('type' => 'string', 'required' => false, 'default' => '', 'filter' => 'trim'); + +$config->account->form->edit = $config->account->form->create;; diff --git a/module/account/control.php b/module/account/control.php index 6c96b08c01..62860ac3f3 100644 --- a/module/account/control.php +++ b/module/account/control.php @@ -84,18 +84,15 @@ class account extends control * @access public * @return void */ - public function edit($id, $from = 'parent') + public function edit(int $id, string $from = 'parent') { if($_POST) { - $changes = $this->account->update($id); + $account = $this->accountZen->buildDataForEdit(); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - if($changes) - { - $actionID = $this->loadModel('action')->create('account', $id, 'Edited'); - $this->action->logHistory($actionID, $changes); - } + $changes = $this->account->update($id, $account); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse'), 'closeModal' => true)); } @@ -103,10 +100,6 @@ class account extends control $this->view->title = $this->lang->account->edit; $this->view->account = $this->account->getById($id); $this->view->rooms = $this->loadModel('serverroom')->getPairs(); - $this->view->from = $from; - - $this->view->position[] = html::a($this->createLink('account', 'browse'), $this->lang->account->common); - $this->view->position[] = $this->lang->account->edit; $this->display(); } diff --git a/module/account/model.php b/module/account/model.php index 9a0ebe5b1c..a922390244 100644 --- a/module/account/model.php +++ b/module/account/model.php @@ -18,7 +18,7 @@ class accountModel extends model * @access public * @return object */ - public function getByID($id) + public function getByID(int $id): object|false { return $this->dao->select('*')->from(TABLE_ACCOUNT)->where('id')->eq($id)->fetch(); } @@ -113,26 +113,29 @@ class accountModel extends model * Update one account. * * @param int $id + * @param object $account * @access public - * @return void + * @return bool */ - public function update($id) + public function update(int $id, object $account): bool { - $now = helper::now(); $oldAccount = $this->getByID($id); - $newAccount = fixer::input('post') - ->add('editedBy', $this->app->user->account) - ->add('editedDate', $now) - ->get(); - - $this->dao->update(TABLE_ACCOUNT)->data($newAccount)->autoCheck() + $this->dao->update(TABLE_ACCOUNT)->data($account)->autoCheck() ->batchCheck($this->config->account->edit->requiredFields, 'notempty') - ->checkIf($newAccount->email, 'email', 'email') - ->checkIf($newAccount->mobile, 'mobile', 'mobile') + ->checkIf($account->email, 'email', 'email') + ->checkIf($account->mobile, 'mobile', 'mobile') ->where('id')->eq($id) ->exec(); - if(!dao::isError()) return common::createChanges($oldAccount, $newAccount); + if(!dao::isError()) + { + $changes = common::createChanges($oldAccount, $account); + if(empty($changes)) return true; + + $actionID = $this->loadModel('action')->create('account', $id, 'Edited'); + $this->action->logHistory($actionID, $changes); + return true; + } return false; } } diff --git a/module/account/test/model/getbyid.php b/module/account/test/model/getbyid.php new file mode 100644 index 0000000000..df12d51e74 --- /dev/null +++ b/module/account/test/model/getbyid.php @@ -0,0 +1,20 @@ +#!/usr/bin/env php +gen(10); + +/** + +title=accountModel->getByID(); +timeout=0 +cid=1 + +*/ + +global $tester; +$accountModel = $tester->loadModel('account'); +r($accountModel->getByID(0)) && p() && e('0'); // 获取空数据。 +r((array)$accountModel->getByID(1)) && p('id,name,provider') && e('1,运维账号1,qingyun'); // 获取id=1的数据。 diff --git a/module/account/test/model/update.php b/module/account/test/model/update.php new file mode 100644 index 0000000000..4a448d10a8 --- /dev/null +++ b/module/account/test/model/update.php @@ -0,0 +1,39 @@ +#!/usr/bin/env php +gen(5); + +/** + +title=accountModel->update(); +timeout=0 +cid=1 + +*/ + +$account = new stdclass(); +$account->name = '测试账号'; +$account->provider = 'aliyun'; +$account->adminURI = ''; +$account->account = 'admin'; +$account->password = 'admin'; +$account->email = 'admin@163.com'; +$account->mobile = ''; +$account->type = ''; +$account->status = ''; +$account->extra = ''; +$account->createdBy = 'admin'; +$account->createdDate = date('Y-m-d H:i:s'); + +global $tester; +$accountID = 1; +$accountModel = $tester->loadModel('account'); +$oldAccount = $accountModel->getByID($accountID); +$accountModel->update($accountID, $account); +$newAccount = $accountModel->getByID($accountID); + +r($oldAccount) && p('id,name,provider') && e('1,运维账号1,qingyun'); // 检查插入数据库的数据。 +r($newAccount) && p('id,name,provider,account,password') && e('1,测试账号,aliyun,admin,admin'); // 检查插入数据库的数据。 diff --git a/module/account/zen.php b/module/account/zen.php index bc3612adc8..73821c2535 100644 --- a/module/account/zen.php +++ b/module/account/zen.php @@ -19,8 +19,21 @@ class accountZen extends account */ protected function buildDataForCreate(): object { - return form::data()->setDefault('createdBy', $this->app->user->account) - ->setDefault('createdDate', helper::now()) + return form::data()->add('createdBy', $this->app->user->account) + ->add('createdDate', helper::now()) + ->get(); + } + + /** + * Build account data for edit method. + * + * @access protected + * @return object + */ + protected function buildDataForEdit(): object + { + return form::data()->add('editedBy', $this->app->user->account) + ->add('editedDate', helper::now()) ->get(); } } diff --git a/module/serverroom/model.php b/module/serverroom/model.php index 2cfc1d6229..39d9afa7e5 100644 --- a/module/serverroom/model.php +++ b/module/serverroom/model.php @@ -73,7 +73,7 @@ class serverroomModel extends model * @access public * @return array */ - public function getPairs() + public function getPairs(): array { $stmt = $this->dao->select('*')->from(TABLE_SERVERROOM) ->where('deleted')->eq('0') diff --git a/module/serverroom/test/model/getpairs.php b/module/serverroom/test/model/getpairs.php new file mode 100644 index 0000000000..c5944b5b68 --- /dev/null +++ b/module/serverroom/test/model/getpairs.php @@ -0,0 +1,21 @@ +#!/usr/bin/env php +gen(10); + +/** + +title=serverroomModel->getPairs(); +timeout=0 +cid=1 + +*/ + +global $tester; +$roomModel = $tester->loadModel('serverroom'); +$pairs = $roomModel->getPairs(); +r(count($pairs)) && p() && e('11'); // 检查记录数。 +r($pairs) && p('0,10') && e('``,北京 - 青云 - 这是机房名称10'); // 检查0和10的数据。 diff --git a/test/data/serverroom.yaml b/test/data/serverroom.yaml index a189b0e2d9..f3665e01e2 100644 --- a/test/data/serverroom.yaml +++ b/test/data/serverroom.yaml @@ -47,44 +47,35 @@ fields: format: "" - field: owner note: "负责人" - from: common.user.v1.yaml - use: user - prefix: "" - postfix: "" - loop: 0 - format: "" + fields: + - field: account1 + range: admin,user{99},test{100},dev{100},pm{100},po{100},td{100},pd{100},qd{100},top{100},outside{100},others{100},a,bb,ccc,qwuiadsd?!2as@#%$aasd~aj1!@#1 + - field: account2 + range: "[],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4}" - field: createdBy note: "创建者" - from: common.user.v1.yaml - use: user - prefix: "" - postfix: "" - loop: 0 - format: "" + fields: + - field: account1 + range: admin,user{99},test{100},dev{100},pm{100},po{100},td{100},pd{100},qd{100},top{100},outside{100},others{100},a,bb,ccc,qwuiadsd?!2as@#%$aasd~aj1!@#1 + - field: account2 + range: "[],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4}" - field: createdDate note: "创建日期" - from: common.date.v1.yaml - use: dateA - prefix: "" - postfix: "" - loop: 0 - format: "" + range: "(-1M)-(+1w):-1D" + type: timestamp + format: "YYYY-MM-DD hh:mm:ss" - field: editedBy note: "编辑者" - from: common.user.v1.yaml - use: user - prefix: "" - postfix: "" - loop: 0 - format: "" + fields: + - field: account1 + range: admin,user{99},test{100},dev{100},pm{100},po{100},td{100},pd{100},qd{100},top{100},outside{100},others{100},a,bb,ccc,qwuiadsd?!2as@#%$aasd~aj1!@#1 + - field: account2 + range: "[],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4}" - field: editedDate note: "编辑日期" - from: common.date.v1.yaml - use: dateA - prefix: "" - postfix: "" - loop: 0 - format: "" + range: "(-1M)-(+1w):-1D" + type: timestamp + format: "YYYY-MM-DD hh:mm:ss" - field: deleted note: "是否删除" range: 0 From 49b6eab2739df30daf08b9186f594729bdf8173d Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 10:25:36 +0800 Subject: [PATCH 191/235] * Adjust manage view group style. --- module/group/ui/manageview.html.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module/group/ui/manageview.html.php b/module/group/ui/manageview.html.php index 9a330315d3..29e0298a5f 100644 --- a/module/group/ui/manageview.html.php +++ b/module/group/ui/manageview.html.php @@ -162,6 +162,7 @@ formPanel set::className('items-center hidden'), formGroup ( + setClass('items-center'), set::label($lang->group->programList), $programs ? inputGroup ( @@ -196,6 +197,7 @@ formPanel set::className('items-center hidden'), formGroup ( + setClass('items-center'), set::label($lang->group->productList), $products ? inputGroup ( @@ -229,6 +231,7 @@ formPanel set::id('projectBox'), formGroup ( + setClass('items-center'), set::label($lang->group->projectList), $projects ? inputGroup ( @@ -262,6 +265,7 @@ formPanel set::id('executionBox'), formGroup ( + setClass('items-center'), set::label($lang->group->executionList), $executions ? inputGroup ( From cb59a6eb7c926f59de7010107c1df5fa7748265d Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 10:25:59 +0800 Subject: [PATCH 192/235] * Skip the loop when there is no privs. --- module/group/control.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module/group/control.php b/module/group/control.php index 5865f52784..3f4c329f1b 100644 --- a/module/group/control.php +++ b/module/group/control.php @@ -36,6 +36,8 @@ class group extends control $allPrivs = array(); foreach($this->config->group->package as $packageCode => $package) { + if(empty($package->privs)) continue; + foreach($package->privs as $privCode => $priv) { $allPrivs[$privCode] = $privCode; From 1d30531143cc75a11bb434c894ba2fc45f7ecb81 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 10:40:58 +0800 Subject: [PATCH 193/235] * Change to new writing method. --- module/story/ui/close.html.php | 4 +-- module/story/ui/create.html.php | 57 +++++++++++++----------------- module/story/ui/linkstory.html.php | 2 +- module/story/ui/view.html.php | 34 +++++++++--------- 4 files changed, 45 insertions(+), 52 deletions(-) diff --git a/module/story/ui/close.html.php b/module/story/ui/close.html.php index 0295007135..e68db95ffa 100644 --- a/module/story/ui/close.html.php +++ b/module/story/ui/close.html.php @@ -20,7 +20,7 @@ formPanel set::submitBtnText($lang->story->closeAction), formGroup ( - set::id('closedReason'), + setID('closedReason'), set::name('closedReason'), set::label($lang->story->closedReason), set::width('1/2'), @@ -31,7 +31,7 @@ formPanel formRow ( set::hidden(true), - set::id('duplicateStoryBox'), + setID('duplicateStoryBox'), formGroup ( set::name('duplicateStory'), diff --git a/module/story/ui/create.html.php b/module/story/ui/create.html.php index 9e031a9709..8d571d30e4 100644 --- a/module/story/ui/create.html.php +++ b/module/story/ui/create.html.php @@ -24,12 +24,12 @@ formPanel ( commonModel::isTutorialMode() ? '' : on::click('#saveButton', 'customSubmit'), on::click('#saveDraftButton', 'customSubmit'), - set::id('dataform'), + setID('dataform'), to::heading(div ( setClass('panel-title text-lg'), $lang->story->create, - !$forceReview ? checkbox(set::id('needNotReview'), set::rootClass('text-base font-medium'), set::value(1), set::text($lang->story->needNotReview), set::checked($needReview), on::change('toggleReviewer(e.target)')) : null + !$forceReview ? checkbox(setID('needNotReview'), set::rootClass('text-base font-medium'), set::value(1), set::text($lang->story->needNotReview), set::checked($needReview), on::change('toggleReviewer(e.target)')) : null )), set::actions(array ( @@ -55,7 +55,7 @@ formPanel ), isset($fields['branch']) && $type == 'story' ? formGroup ( - set::id('assignedToBox'), + setID('assignedToBox'), set::label($lang->story->assignedTo), set::width('1/2'), set::name('assignedTo'), @@ -66,7 +66,7 @@ formPanel set::label($lang->story->module), inputGroup ( - set('id', 'moduleIdBox'), + setID('moduleIdBox'), picker ( set::name('module'), @@ -77,20 +77,17 @@ formPanel ), count($fields['module']['options']) == 1 ? span ( - set('class', 'input-group-addon'), + setClass('input-group-addon'), a ( - set('class', 'mr-2'), + setClass('mr-2'), set('href', $this->createLink('tree', 'browse', "rootID=$productID&view=story¤tModuleID=0&branch={$branch}")), - set('data-toggle', 'modal'), - set('data-size', 'lg'), + setData(array('toggle' => 'modal', 'size' => 'lg')), $lang->tree->manage ), a ( - set('data-on', 'click'), - set('data-call', 'loadProductModules'), - set('data-params', $productID), + setData(array('on' => 'click', 'call' => 'loadProductModules', 'params' => $productID)), icon('refresh') ) ) : null @@ -106,17 +103,14 @@ formPanel set::label(sprintf($lang->product->branch, $lang->product->branchName[$product->type])), inputGroup ( - set::id('branchBox'), + setID('branchBox'), picker ( setID('branches_0'), set::name('branches[0]'), set::items($fields['branches']['options']), set::value($fields['branches']['default']), - set('data-index', '0'), - set('data-on', 'change'), - set('data-call', 'loadBranchRelation'), - set('data-params', 'event') + setData(array('index' => 0, 'on' => 'change', 'call' => 'loadBranchRelation', 'params' => 'event')) ) ) ), @@ -126,7 +120,7 @@ formPanel set::label($lang->story->module), inputGroup ( - set::id('moduleIdBox'), + setID('moduleIdBox'), picker(setID('modules_0'), set::name('modules[0]'), set::items($fields['modules']['options']), set::value($fields['modules']['default']), set::required(true)) ) ), @@ -135,7 +129,7 @@ formPanel set::label($lang->story->plan), inputGroup ( - set::id('planIdBox'), + setID('planIdBox'), picker(setID('plans_0'), set::name('plans[0]'), set::items($fields['plans']['options']), set::value($fields['plans']['default'])) ) ), @@ -143,12 +137,12 @@ formPanel ( set::width('50px'), setClass('c-actions'), - btn(setClass('btn-link addNewLine'), set('data-on', 'click'), set('data-call', 'addBranchesBox'), set('data-params', 'event'), set::title(sprintf($lang->story->addBranch, $lang->product->branchName[$product->type])), icon('plus')) + btn(setClass('btn-link addNewLine'), setData(array('on' => 'click', 'call' => 'addBranchesBox', 'params' => 'event')), set::title(sprintf($lang->story->addBranch, $lang->product->branchName[$product->type])), icon('plus')) ) : null, ) : null, isset($fields['branches']) && $type == 'story' ? formRow ( - set::id('storyNoticeBranch'), + setID('storyNoticeBranch'), setClass('hidden'), formGroup ( @@ -166,17 +160,17 @@ formPanel ( span ( - set::id('planIdBox'), + setID('planIdBox'), picker(set::name('plan'), set::items($fields['plan']['options']), set::value($fields['plan']['default'])) ), - empty($fields['plan']['options']) ? btn(set::url($this->createLink('productplan', 'create', "productID=$productID&branch=$branch")), set('data-toggle', 'modal'), set::title($lang->productplan->create), icon('plus')) : null, + empty($fields['plan']['options']) ? btn(set::url($this->createLink('productplan', 'create', "productID=$productID&branch=$branch")), setData(array('toggle' => 'modal')), set::title($lang->productplan->create), icon('plus')) : null, empty($fields['plan']['options']) ? btn(setClass('refresh'), set::title($lang->refresh), set('onclick', "loadProductPlans($productID)"), icon('refresh')) : null ) ), formGroup ( set::width('1/2'), - set::id('assignedToBox'), + setID('assignedToBox'), set::name('assignedTo'), set::label($lang->story->assignedTo), set::items($fields['assignedTo']['options']), @@ -229,7 +223,7 @@ formPanel set::label($lang->story->assignedTo), inputGroup ( - set::id('assignedToBox'), + setID('assignedToBox'), picker(setID('assignedTo'), set::name('assignedTo'), set::items($fields['assignedTo']['options']), set::value($fields['assignedTo']['default'])) ) ), @@ -256,7 +250,7 @@ formPanel set::required($forceReview), inputGroup ( - set::id('reviewerBox'), + setID('reviewerBox'), picker ( setID('reviewer'), @@ -278,7 +272,7 @@ formPanel inputGroup ( span(setClass('URSBox'), picker(setID('URS'), set::name('URS[]'), set::items($fields['URS']['options']), set::value($fields['URS']['default']))), - btn(set('data-on', 'click'), set('data-call', 'loadURS'), set('data-params', 'allURS'), $lang->story->loadAllStories) + btn(setData(array('on' => 'click', 'call' => 'loadURS', 'params' => 'allURS')), $lang->story->loadMyStories) ) ), formGroup @@ -312,8 +306,7 @@ formPanel set::name('region'), set::items($fields['region']['options']), set::value($fields['region']['default']), - set('data-on', 'change'), - set('data-call', 'setLane') + setData(array('on' => 'change', 'call' => 'setLane')) ), formGroup ( @@ -416,7 +409,7 @@ formPanel isset($fields['branches']) && $type == 'story' ? formRow ( - set::id('addBranchesBox'), + setID('addBranchesBox'), setClass('hidden'), formGroup ( @@ -424,7 +417,7 @@ isset($fields['branches']) && $type == 'story' ? formRow set::label(sprintf($lang->product->branch, $lang->product->branchName[$product->type])), inputGroup ( - set::id('branchBox'), + setID('branchBox'), div(setID('branches'), setClass('form-group-wrapper')) ) ), @@ -434,7 +427,7 @@ isset($fields['branches']) && $type == 'story' ? formRow set::label($lang->story->module), inputGroup ( - set::id('moduleIdBox'), + setID('moduleIdBox'), div(setID('modules'), setClass('form-group-wrapper')) ) ), @@ -443,7 +436,7 @@ isset($fields['branches']) && $type == 'story' ? formRow set::label($lang->story->plan), inputGroup ( - set::id('planIdBox'), + setID('planIdBox'), div(setID('plans'), setClass('form-group-wrapper')) ) ), diff --git a/module/story/ui/linkstory.html.php b/module/story/ui/linkstory.html.php index 4b4d8fff23..7cb143556b 100644 --- a/module/story/ui/linkstory.html.php +++ b/module/story/ui/linkstory.html.php @@ -40,7 +40,7 @@ searchForm dtable ( - set::id('linkStories'), + setID('linkStories'), set::userMap($users), set::cols($cols), set::data($data), diff --git a/module/story/ui/view.html.php b/module/story/ui/view.html.php index 430a8d4578..2ad4485bb5 100644 --- a/module/story/ui/view.html.php +++ b/module/story/ui/view.html.php @@ -33,7 +33,7 @@ $versions = array(); for($i = $story->version; $i >= 1; $i --) $versions[] = array('text' => "#{$i}", 'url' => inlink('view', "storyID={$story->id}&version=$i¶m=0&storyType={$story->type}")); $menus = $this->story->buildOperateMenu($story, 'view', $project ? $project : null); -foreach($menus['dropMenus'] as $dropMenuKey => $dropItems) menu(set::id($dropMenuKey), setClass('menu dropdown-menu'), set::items($dropItems)); +foreach($menus['dropMenus'] as $dropMenuKey => $dropItems) menu(setID($dropMenuKey), setClass('menu dropdown-menu'), set::items($dropItems)); /* Get module items. */ $moduleTitle = ''; @@ -107,7 +107,7 @@ if($story->type == 'story') set::title($task->name), (isset($execution->type) && $execution->type == 'kanban' && $isInModal) ? span(setClass('muted title'), $executionName) : a(set::href($executionLink), setClass('muted title'), $executionName), label(setClass('circle size-sm'), $task->id), - common::hasPriv('task', 'view') ? a(set::href($this->createLink('task', 'view', "taskID=$task->id")), setClass('title'), set('data-toggle', 'modal'), $task->name) : span(setClass('title'), $task->name), + common::hasPriv('task', 'view') ? a(set::href($this->createLink('task', 'view', "taskID=$task->id")), setClass('title'), setData(array('toggle' => 'modal')), $task->name) : span(setClass('title'), $task->name), label(setClass("status-{$task->status} size-sm"), $this->lang->task->statusList[$task->status]) ); } @@ -262,13 +262,13 @@ detailBody ) : null, item ( - set::id('source'), + setID('source'), set::name($lang->story->source), zget($lang->story->sourceList, $story->source, '') ), item ( - set::id('sourceNoteBox'), + setID('sourceNoteBox'), set::name($lang->story->sourceNote), $story->sourceNote ), @@ -396,9 +396,9 @@ detailBody setClass('twins'), $branch ? label(setClass($labelClass . ' circle branch size-sm'), set::title($branch), $branch) : null, label(setClass('circle size-sm'), $twin->id), - common::hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "id={$twin->id}")), setClass('title'), set::title($twin->title), set('data-toggle', 'modal'), $twin->title) : span(setClass('title'), $twin->title), + common::hasPriv('story', 'view') ? a(set::href($this->createLink('story', 'view', "id={$twin->id}")), setClass('title'), set::title($twin->title), setData(array('toggle' => 'modal')), $twin->title) : span(setClass('title'), $twin->title), label(setClass('size-sm'), set::title($stage), $stage), - common::hasPriv('story', 'relieved') ? a(set::title($lang->story->relievedTwins), setClass("relievedTwins unlink hidden size-xs"), on::click('unlinkTwins'), set('data-id', $twin->id), icon('unlink')) : null + common::hasPriv('story', 'relieved') ? a(set::title($lang->story->relievedTwins), setClass("relievedTwins unlink hidden size-xs"), on::click('unlinkTwins'), setData(array('id' => $twin->id)), icon('unlink')) : null ); }, $twins)) ) @@ -421,11 +421,11 @@ detailBody setClass('relateStories'), set::title($relation->title), label(setClass('circle size-sm'), $relation->id), - $canViewStory ? a(set::href(helper::createLink('story', 'view', "id={$relation->id}&version=0¶m=0&storyType=$relationType")), setClass('title'), set('data-toggle', 'modal'), $relation->title) : span(setClass('title'), $relation->title), + $canViewStory ? a(set::href(helper::createLink('story', 'view', "id={$relation->id}&version=0¶m=0&storyType=$relationType")), setClass('title'), setData(array('toggle' => 'modal')), $relation->title) : span(setClass('title'), $relation->title), $canLinkStory ? a(set('url', helper::createLink('story', 'linkStory', "storyID=$story->id&type=remove&linkedID={$relation->id}&browseType=&queryID=0&storyType=$story->type")), setClass('unlink unlinkStory hidden'), icon('link')) : null ); }, $relations)), - !common::hasPriv($story->type, 'linkStory') ? null : h::li(a(set::href(helper::createLink('story', 'linkStory', "storyID=$story->id&type=linkStories&linkedID=0&browseType=&queryID=0&storyType=$story->type")), set('data-toggle', 'modal'), set('data-size', 'lg'), set::id('linkButton'), setClass('btn secondary size-sm'), icon('plus'), $lang->story->link . ($story->type == 'story' ? $lang->story->requirement : $lang->story->story))) + !common::hasPriv($story->type, 'linkStory') ? null : h::li(a(set::href(helper::createLink('story', 'linkStory', "storyID=$story->id&type=linkStories&linkedID=0&browseType=&queryID=0&storyType=$story->type")), setData(array('toggle' => 'modal', 'size' => 'lg')), setID('linkButton'), setClass('btn secondary size-sm'), icon('plus'), $lang->story->link . ($story->type == 'story' ? $lang->story->requirement : $lang->story->story))) ) ) : null, $story->type == 'story' && common::hasPriv('story', 'tasks') ? tabPane @@ -452,7 +452,7 @@ detailBody ( set::title($fromBug->title), label(setClass('circle size-sm'), $fromBug->id), - common::hasPriv('bug', 'view') ? a(set::href($this->createLink('bug', 'view', "bugID=$fromBug->id")), setClass('title'), set('data-toggle', 'modal'), set::title($fromBug->title), $fromBug->title) : span(setClass('title'), $fromBug->title) + common::hasPriv('bug', 'view') ? a(set::href($this->createLink('bug', 'view', "bugID=$fromBug->id")), setClass('title'), setData(array('toggle' => 'modal')), set::title($fromBug->title), $fromBug->title) : span(setClass('title'), $fromBug->title) ) ) ) : null, @@ -468,7 +468,7 @@ detailBody ( set::title($bug->title), label(setClass('circle size-sm'), $bug->id), - common::hasPriv('bug', 'view') ? a(set::href(helper::createLink('bug', 'view', "bugID=$bug->id")), setClass('title'), set('data-toggle', 'modal'), set::title($bug->title), $bug->title) : span(setClass('title'), $bug->title), + common::hasPriv('bug', 'view') ? a(set::href(helper::createLink('bug', 'view', "bugID=$bug->id")), setClass('title'), setData(array('toggle' => 'modal')), set::title($bug->title), $bug->title) : span(setClass('title'), $bug->title), label(setClass("status-{$bug->status} size-sm"), $lang->bug->statusList[$bug->status]) ); }, $bugs)) @@ -486,7 +486,7 @@ detailBody ( set::title($case->title), label(setClass('circle size-sm'), $case->id), - common::hasPriv('testcase', 'view') ? a(set::href(helper::createLink('testcase', 'view', "caseID=$case->id")), setClass('title'), set('data-toggle', 'modal'), set::title($case->title), $case->title) : span(setClass('title'), $case->title) + common::hasPriv('testcase', 'view') ? a(set::href(helper::createLink('testcase', 'view', "caseID=$case->id")), setClass('title'), setData(array('toggle' => 'modal')), set::title($case->title), $case->title) : span(setClass('title'), $case->title) ); }, $cases)) ) @@ -505,7 +505,7 @@ detailBody ( set::title($build->name), label(setClass('circle size-sm'), $build->id), - common::hasPriv('build', 'view') ? a(set::href(helper::createLink('build', 'view', "buildID=$build->id")), setClass('title'), set('data-app', $tab), set::title($build->name), $build->name) : span(setClass('title'), $build->name) + common::hasPriv('build', 'view') ? a(set::href(helper::createLink('build', 'view', "buildID=$build->id")), setClass('title'), setData(array('app' => $tab)), set::title($build->name), $build->name) : span(setClass('title'), $build->name) ); }, $builds)) ) @@ -525,7 +525,7 @@ detailBody ( set::title($release->name), label(setClass('circle size-sm'), $release->id), - common::hasPriv($releaseModule, 'view') ? a(set::href(helper::createLink($releaseModule, 'view', "releaseID=$release->id")), setClass('title'), set('data-app', $tab), set::title($release->name), $release->name) : span(setClass('title'), $release->name) + common::hasPriv($releaseModule, 'view') ? a(set::href(helper::createLink($releaseModule, 'view', "releaseID=$release->id")), setClass('title'), setData(array('app' => $tab)), set::title($release->name), $release->name) : span(setClass('title'), $release->name) ); }, $releases)) ) @@ -544,7 +544,7 @@ detailBody ( set::title($storyTitle), label(setClass('circle size-sm'), $storyID), - $hasPriv ? a(set::href(helper::createLink('story', 'view', "storyID=$storyID&version=0¶m=0&storyType=$story->type")), setClass('title'), set('data-toggle', 'modal'), set::title($storyTitle), $storyTitle) : span(setClass('title'), $storyTitle) + $hasPriv ? a(set::href(helper::createLink('story', 'view', "storyID=$storyID&version=0¶m=0&storyType=$story->type")), setClass('title'), setData(array('toggle' => 'modal')), set::title($storyTitle), $storyTitle) : span(setClass('title'), $storyTitle) ); }, array_keys($story->linkStoryTitles), array_values($story->linkStoryTitles))) ) @@ -566,7 +566,7 @@ detailBody set::href(helper::createLink('mr', 'view', "MRID=$MRID")), setClass('title'), set::title($linkMRTitle), - set('data-app', 'devops'), + setData(array('app', 'devops')), $linkMRTitle ) : span(setClass('title'), $linkMRTitle) ); @@ -590,7 +590,7 @@ detailBody set::href(helper::createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}")), setClass('title'), set::title($commit->comment), - set('data-app', 'devops'), + setData(array('app' => 'devops')), $commit->comment ) : span(setClass('title'), $commit->comment) ); @@ -607,7 +607,7 @@ if(isset($libs)) { modal ( - set::id('importToLib'), + setID('importToLib'), set::title($lang->story->importToLib), form ( From 4e063d3b610261690e2da6e1e701021420171bb2 Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 02:55:02 +0000 Subject: [PATCH 194/235] * Adjust type. --- module/story/control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/story/control.php b/module/story/control.php index 7604006360..b928e06aba 100755 --- a/module/story/control.php +++ b/module/story/control.php @@ -435,7 +435,7 @@ class story extends control if(isInModal()) { - $execution = $this->execution->getByID($this->session->execution); + $execution = $this->execution->getByID((int)$this->session->execution); if($this->app->tab == 'execution' and $execution->type == 'kanban') { $executionLaneType = $this->session->executionLaneType ? $this->session->executionLaneType : 'all'; From e1da78f94a642e79049001b09610fe81ef9f7cc9 Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 02:55:46 +0000 Subject: [PATCH 195/235] * Format codes. --- module/product/ui/all.html.php | 2 +- module/product/ui/browse.html.php | 9 +++------ module/product/ui/dynamic.html.php | 5 +---- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/module/product/ui/all.html.php b/module/product/ui/all.html.php index 7a51f8d227..46e5ef8942 100644 --- a/module/product/ui/all.html.php +++ b/module/product/ui/all.html.php @@ -119,7 +119,7 @@ toolbar ) : null ); -$canBatchEdit = common::hasPriv('product', 'batchEdit'); +$canBatchEdit = hasPriv('product', 'batchEdit'); dtable ( set::id('products'), diff --git a/module/product/ui/browse.html.php b/module/product/ui/browse.html.php index 192c1a1593..6d07eab25b 100644 --- a/module/product/ui/browse.html.php +++ b/module/product/ui/browse.html.php @@ -279,10 +279,7 @@ $fnGenerateFootToolbar = function() use ($lang, $product, $productID, $project, /* Layout. */ global $app; -if($app->rawModule == 'projectstory' && !empty($project)) -{ - dropmenu(set::text($project->name)); -} +if($app->rawModule == 'projectstory' && !empty($project)) dropmenu(set::text($project->name)); data('storyBrowseType', $storyBrowseType); @@ -308,8 +305,8 @@ featureBar toolbar ( - (!common::hasPriv('story', 'report') || !$productID) ? null : item(set(array('id' => 'reportBtn', 'text' => $lang->project->report, 'icon' => 'bar-chart', 'class' => 'ghost', 'url' => helper::createLink('story', 'report', "productID=$productID&branchID=$branch&storyType=$storyType&browseType=$browseType&moduleID=$moduleID&chartType=pie&projectID=$projectID")))), - !common::hasPriv('story', 'export') ? null : item(set(array('id' => 'exportBtn', 'text' => $lang->export, 'icon' => 'export', 'class' => 'ghost', 'url' => helper::createLink('story', 'export', "productID=$productID&orderBy=$orderBy&executionID=$projectID&browseType=$browseType&storyType=$storyType"), 'data-toggle' => 'modal'))), + (!hasPriv('story', 'report') || !$productID) ? null : item(set(array('id' => 'reportBtn', 'text' => $lang->project->report, 'icon' => 'bar-chart', 'class' => 'ghost', 'url' => helper::createLink('story', 'report', "productID=$productID&branchID=$branch&storyType=$storyType&browseType=$browseType&moduleID=$moduleID&chartType=pie&projectID=$projectID")))), + !hasPriv('story', 'export') ? null : item(set(array('id' => 'exportBtn', 'text' => $lang->export, 'icon' => 'export', 'class' => 'ghost', 'url' => helper::createLink('story', 'export', "productID=$productID&orderBy=$orderBy&executionID=$projectID&browseType=$browseType&storyType=$storyType"), 'data-toggle' => 'modal'))), $fnBuildCreateStoryButton(), $fnBuildLinkStoryButton() ); diff --git a/module/product/ui/dynamic.html.php b/module/product/ui/dynamic.html.php index 5d737a4953..90aa2fd6ff 100644 --- a/module/product/ui/dynamic.html.php +++ b/module/product/ui/dynamic.html.php @@ -62,10 +62,7 @@ foreach($dateGroups as $date => $actions) div ( setClass('cursor-pointer leading-5'), - span(icon - ( - 'angle-down text-primary border-2 rounded-full z-10 bg-canvas align-middle dynamic-collapse-icon' - )), + span(icon('angle-down text-primary border-2 rounded-full z-10 bg-canvas align-middle dynamic-collapse-icon')), span ( setClass('ml-2'), From fe13bc37bbad419934b4baa6990f4f740142a1c7 Mon Sep 17 00:00:00 2001 From: songchenxuan Date: Mon, 20 Nov 2023 11:00:19 +0800 Subject: [PATCH 196/235] * Use helper today for metric. --- module/metric/tao.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/module/metric/tao.php b/module/metric/tao.php index 2c1d3054c7..255499d0ab 100644 --- a/module/metric/tao.php +++ b/module/metric/tao.php @@ -160,9 +160,7 @@ class metricTao extends metricModel } else { - $maxDate = $this->dao->select("max(date) maxDate")->from(TABLE_METRICLIB)->fetch('maxDate'); - $date = substr($maxDate, 0, 10); - $date = helper::now(); + $date = helper::today(); } } From fb7a890ec70be9076b1f0eb3bf4e8494d6c66b3c Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 11:00:16 +0800 Subject: [PATCH 197/235] * Jump to the error page if no products in testsuite. --- module/testsuite/control.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/module/testsuite/control.php b/module/testsuite/control.php index e84dbd2140..f03d845906 100644 --- a/module/testsuite/control.php +++ b/module/testsuite/control.php @@ -40,7 +40,12 @@ class testsuite extends control parent::__construct($moduleName, $methodName); $this->view->products = $this->products = $this->loadModel('product')->getPairs('', 0, '', 'all'); - if(empty($this->products) && !helper::isAjaxRequest()) return $this->send(array('result' => 'fail', 'open' => $this->createLink('product', 'showErrorNone', 'moduleName=qa&activeMenu=testsuite'))); + if(empty($products) && (helper::isAjaxRequest('zin') || helper::isAjaxRequest('fetch'))) + { + $tab = $this->app->tab == 'project' || $this->app->tab == 'execution' ? $this->app->tab : 'qa'; + $objectID = $tab == 'project' || $tab == 'execution' ? $this->session->{$tab} : 0; + $this->locate($this->createLink('product', 'showErrorNone', "moduleName={$tab}&activeMenu=testsuite&objectID=$objectID")); + } } /** From 10f51f25ebf043bcf9465025b116e522a2087cde Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 11:01:15 +0800 Subject: [PATCH 198/235] * Modify the condition for jumping to the error page in testreport. --- module/testreport/control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/testreport/control.php b/module/testreport/control.php index 59cdf39cd3..5bde9e22fd 100644 --- a/module/testreport/control.php +++ b/module/testreport/control.php @@ -64,7 +64,7 @@ class testreport extends control { $products = $this->product->getPairs(); } - if(empty($products) and !helper::isAjaxRequest()) return print($this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=testreport&objectID=$objectID"))); + if(empty($products) && !isInModal() && (helper::isAjaxRequest('zin') || helper::isAjaxRequest('fetch'))) $this->locate($this->createLink('product', 'showErrorNone', "moduleName={$tab}&activeMenu=testreport&objectID=$objectID")); } else { From 36eae836bcd67e45f991a09532ac631e5e4d8b16 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Mon, 20 Nov 2023 11:02:08 +0800 Subject: [PATCH 199/235] * Fix count_of_assigned_case_in_user. --- .../metric/calc/user/scale/count_of_assigned_case_in_user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/metric/calc/user/scale/count_of_assigned_case_in_user.php b/module/metric/calc/user/scale/count_of_assigned_case_in_user.php index d9a2943407..fc5ad434d5 100755 --- a/module/metric/calc/user/scale/count_of_assigned_case_in_user.php +++ b/module/metric/calc/user/scale/count_of_assigned_case_in_user.php @@ -27,7 +27,7 @@ class count_of_assigned_case_in_user extends baseCalc return $this->dao->select('t1.assignedTo')->from(TABLE_TESTRUN)->alias('t1') ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id') ->leftJoin(TABLE_TESTTASK)->alias('t3')->on('t1.task = t3.id') - ->andWhere('t3.deleted')->eq(0) + ->where('t3.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t3.status')->ne('done') ->query(); From 41c16999ce75b20d3d3fc19e0b6f0c5a5171e73e Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 11:02:24 +0800 Subject: [PATCH 200/235] * Modify the condition for jumping to the error page in testtask. --- module/testtask/control.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/testtask/control.php b/module/testtask/control.php index 408a2fc0d8..711a664afc 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -46,13 +46,13 @@ class testtask extends control { $products = $this->testtaskZen->getProducts(); - /* 如果没有获取到产品键值对、并且即不是弹窗页面也不是 ajax 请求,那么跳转到错误提示页面。*/ - /* If the product key-value pair is not obtained and it is not a pop-up page or an ajax request, then jump to the error page. */ - if(empty($products) && !isInModal() && !helper::isAjaxRequest()) + /* 如果没有获取到产品键值对、并且即不是弹窗页面,并且是 zin 或者 fetch 请求,那么跳转到错误提示页面。*/ + /* If the product key-value pair is not obtained and it is not a pop-up page, and it is a zin request or a fetch request, then jump to the error page. */ + if(empty($products) && !isInModal() && (helper::isAjaxRequest('zin') || helper::isAjaxRequest('fetch'))) { $tab = ($this->app->tab == 'project' || $this->app->tab == 'execution') ? $this->app->tab : 'qa'; $objectID = ($tab == 'project' || $tab == 'execution') ? $this->session->$tab : 0; - helper::end($this->locate($this->createLink('product', 'showErrorNone', "moduleName=$tab&activeMenu=testtask&objectID=$objectID"))); + $this->locate($this->createLink('product', 'showErrorNone', "moduleName={$tab}&activeMenu=testtask&objectID=$objectID")); } $this->products = $products; From c9682a918340e73b92bedb665a83474abbd54050 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Mon, 20 Nov 2023 11:05:28 +0800 Subject: [PATCH 201/235] * Modify url in execution::linkStory. --- module/execution/ui/linkstory.html.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/execution/ui/linkstory.html.php b/module/execution/ui/linkstory.html.php index 59162c455c..1ffc751ed4 100644 --- a/module/execution/ui/linkstory.html.php +++ b/module/execution/ui/linkstory.html.php @@ -49,6 +49,7 @@ if(!isInModal()) ); } +$objectType = $object->type == 'project' ? 'project' : 'execution'; dtable ( set::groupDivider(true), @@ -60,7 +61,7 @@ dtable set::showToolbarOnChecked(false), set::footToolbar($footToolbar), set::footPager(usePager(array( - 'linkCreator' => helper::createLink($object->type, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&recPerPage={recPerPage}&page={page}&extra=$extra") + 'linkCreator' => helper::createLink($objectType, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&recPerPage={recPerPage}&page={page}&extra=$extra") ))) ); From 0d1689c23db8c927d26e94e52748ededf6aaa212 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 11:07:50 +0800 Subject: [PATCH 202/235] * search: support to use datepicker in searchForm. --- module/search/ui/buildform.html.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/module/search/ui/buildform.html.php b/module/search/ui/buildform.html.php index 5948c1574a..5cb5f1f0bd 100644 --- a/module/search/ui/buildform.html.php +++ b/module/search/ui/buildform.html.php @@ -16,6 +16,11 @@ foreach($fieldParams as $name => $param) $condition->defaultOperator = $param['operator']; $condition->placeholder = ''; + if(isset($param['class']) && in_array('date', explode(' ', $param['class']))) + { + $condition->control = 'date'; + } + if(is_array($param['values'])) { $condition->items = array(); From 718ba4d86df0baf7035b44cd226d53176c817927 Mon Sep 17 00:00:00 2001 From: wangyuting Date: Mon, 20 Nov 2023 03:17:38 +0000 Subject: [PATCH 203/235] * Change the control of the date input from input to date. --- module/account/config/search.php | 4 ++-- module/action/config.php | 2 +- module/api/config.php | 4 ++-- module/bug/config/search.php | 14 ++++++------ module/build/config.php | 2 +- module/company/config.php | 4 ++-- module/design/config.php | 2 +- module/doc/config.php | 4 ++-- module/execution/config.php | 34 ++++++++++++++-------------- module/host/config/search.php | 4 ++-- module/product/config/search.php | 14 ++++++------ module/productplan/config/search.php | 4 ++-- module/project/config.php | 14 ++++++------ module/release/config.php | 2 +- module/serverroom/config/search.php | 4 ++-- module/stakeholder/config.php | 2 +- module/testcase/config.php | 6 ++--- module/zahost/config.php | 6 ++--- 18 files changed, 63 insertions(+), 63 deletions(-) diff --git a/module/account/config/search.php b/module/account/config/search.php index 75a836787e..2e4df204de 100644 --- a/module/account/config/search.php +++ b/module/account/config/search.php @@ -20,6 +20,6 @@ $config->account->search['params']['account'] = array('operator' => 'includ $config->account->search['params']['email'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->account->search['params']['mobile'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->account->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->account->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->account->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->account->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->account->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->account->search['params']['editedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/action/config.php b/module/action/config.php index d04cbfdf99..6d6889cd68 100755 --- a/module/action/config.php +++ b/module/action/config.php @@ -102,4 +102,4 @@ $config->trash->search['fields']['date'] = $lang->action->dateAB; $config->trash->search['params']['objectName'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->trash->search['params']['objectID'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->trash->search['params']['actor'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->trash->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->trash->search['params']['date'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/api/config.php b/module/api/config.php index eafeafb804..921a4a6e9b 100644 --- a/module/api/config.php +++ b/module/api/config.php @@ -47,9 +47,9 @@ $config->api->search['params']['title'] = array('operator' => 'include', 'c $config->api->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->api->search['params']['lib'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->api->search['params']['addedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->api->search['params']['addedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->api->search['params']['addedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->api->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->api->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->api->search['params']['editedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->api->search['params']['path'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->api->search['params']['method'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->api->methodOptions); $config->api->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->api->statusOptions); diff --git a/module/bug/config/search.php b/module/bug/config/search.php index cb7ee71233..462805a0f8 100644 --- a/module/bug/config/search.php +++ b/module/bug/config/search.php @@ -79,11 +79,11 @@ $config->bug->search['params']['lastEditedBy'] = array('operator' => '=', $config->bug->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users'); $config->bug->search['params']['openedBuild'] = array('operator' => 'include', 'control' => 'select', 'values' => 'builds'); $config->bug->search['params']['resolvedBuild'] = array('operator' => '=', 'control' => 'select', 'values' => 'builds'); -$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['deadline'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->bug->search['params']['deadline'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/build/config.php b/module/build/config.php index 77daf148c8..1567940599 100644 --- a/module/build/config.php +++ b/module/build/config.php @@ -24,7 +24,7 @@ $config->build->search['params']['name'] = array('operator' => 'include', 'c $config->build->search['params']['product'] = array('operator' => '=', 'control' => 'select', 'values' => 'products'); $config->build->search['params']['scmPath'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->build->search['params']['filePath'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); -$config->build->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->build->search['params']['date'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->build->search['params']['builder'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->build->search['params']['desc'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); diff --git a/module/company/config.php b/module/company/config.php index 383037d0ba..0a33d57d98 100644 --- a/module/company/config.php +++ b/module/company/config.php @@ -26,7 +26,7 @@ $config->company->dynamic->search['params']['execution'] = array('operator' => $config->company->dynamic->search['params']['actor'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->company->dynamic->search['params']['objectID'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->company->dynamic->search['params']['objectType'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->action->search->objectTypeList); -$config->company->dynamic->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->company->dynamic->search['params']['date'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->company->dynamic->search['params']['action'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->company->browse = new stdClass(); @@ -57,7 +57,7 @@ $config->company->browse->search['params']['dept'] = array('operator' => 'be $config->company->browse->search['params']['account'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->company->browse->search['params']['role'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->user->roleList); $config->company->browse->search['params']['phone'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); -$config->company->browse->search['params']['join'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->company->browse->search['params']['join'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->company->browse->search['params']['visions'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->visionList); $config->company->browse->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->company->browse->search['params']['commiter'] = array('operator' => 'include', 'control' => 'select', 'values' => ''); diff --git a/module/design/config.php b/module/design/config.php index 1b90e51201..1ace001529 100644 --- a/module/design/config.php +++ b/module/design/config.php @@ -31,7 +31,7 @@ $config->design->search['params']['type'] = array('operator' => '=', 'con $config->design->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->design->search['params']['commit'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->design->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->design->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->design->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->design->search['params']['assignedTo'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->design->search['params']['story'] = array('operator' => '=', 'control' => 'select', 'values' => ''); diff --git a/module/doc/config.php b/module/doc/config.php index 7ed57889fc..ea8a0035fe 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -81,9 +81,9 @@ $config->doc->search['params']['module'] = array('operator' => 'belong', 'c if($app->rawMethod == 'contribute') $config->doc->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->doc->search['params']['execution'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->doc->search['params']['addedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->doc->search['params']['addedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->doc->search['params']['addedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->doc->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->doc->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->doc->search['params']['editedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->doc->search['params']['keywords'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->doc->search['params']['version'] = array('operator' => '=', 'control' => 'input', 'values' => ''); diff --git a/module/execution/config.php b/module/execution/config.php index 0ee86a1001..77aac1ec01 100644 --- a/module/execution/config.php +++ b/module/execution/config.php @@ -109,16 +109,16 @@ $config->execution->search['params']['lastEditedBy'] = array('operator' => '=' $config->execution->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users'); -$config->execution->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['deadline'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['estStarted'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['realStarted'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['finishedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['canceledDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->execution->search['params']['openedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['deadline'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['estStarted'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['realStarted'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['finishedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['closedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['canceledDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $app->loadLang('execution'); $config->execution->all = new stdclass(); @@ -145,14 +145,14 @@ $config->execution->all->search['params']['status'] = array('operator' = $config->execution->all->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->execution->all->search['params']['PM'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->execution->all->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->execution->all->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->all->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->all->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->all->search['params']['realBegan'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->all->search['params']['realEnd'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->execution->all->search['params']['openedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->all->search['params']['begin'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->all->search['params']['end'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->all->search['params']['realBegan'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->all->search['params']['realEnd'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->execution->all->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->execution->all->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->execution->all->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->execution->all->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->execution->all->search['params']['closedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->execution->all->search['params']['teamCount'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->printKanban = new stdClass(); diff --git a/module/host/config/search.php b/module/host/config/search.php index 85261a7baa..c9f58706fe 100644 --- a/module/host/config/search.php +++ b/module/host/config/search.php @@ -27,6 +27,6 @@ $config->host->search['params']['status'] = array('operator' => '=', 'contr $config->host->search['params']['osName'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->host->search['params']['osVersion'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->host->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->host->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->host->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->host->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->host->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->host->search['params']['editedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/product/config/search.php b/module/product/config/search.php index d815ca2b27..305d6706cd 100644 --- a/module/product/config/search.php +++ b/module/product/config/search.php @@ -68,12 +68,12 @@ $config->product->search['params']['mailto'] = array('operator' => 'incl $config->product->search['params']['closedReason'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->story->reasonList); $config->product->search['params']['version'] = array('operator' => '>=', 'control' => 'input', 'values' => ''); -$config->product->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->product->search['params']['reviewedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->product->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->product->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->product->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->product->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->product->search['params']['openedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->product->search['params']['reviewedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->product->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->product->search['params']['closedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->product->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->product->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $app->loadLang('product'); if(!isset($config->product->all)) $config->product->all = new stdclass(); @@ -109,5 +109,5 @@ $config->product->all->search['params']['QD'] = array('operator' => '=' $config->product->all->search['params']['RD'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->product->all->search['params']['reviewer'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users'); $config->product->all->search['params']['type'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->product->typeList); -$config->product->all->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->product->all->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->product->all->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); diff --git a/module/productplan/config/search.php b/module/productplan/config/search.php index b04d0c52b5..2b99e79d08 100644 --- a/module/productplan/config/search.php +++ b/module/productplan/config/search.php @@ -13,6 +13,6 @@ $config->productplan->search['params']['id'] = array('operator' => '=', $config->productplan->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->productplan->search['params']['branch'] = array('operator' => 'include', 'control' => 'select', 'values' => ''); $config->productplan->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->productplan->statusList); -$config->productplan->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->productplan->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->productplan->search['params']['begin'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->productplan->search['params']['end'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/project/config.php b/module/project/config.php index 50451e1df1..1dca50df85 100644 --- a/module/project/config.php +++ b/module/project/config.php @@ -92,15 +92,15 @@ $config->project->search['params']['parent'] = array('operator' => '=' $config->project->search['params']['status'] = array('operator' => '=' , 'control' => 'select', 'values' => $lang->project->statusList); $config->project->search['params']['desc'] = array('operator' => 'include', 'control' => 'input' , 'values' => ''); $config->project->search['params']['PM'] = array('operator' => '=' , 'control' => 'select', 'values' => 'users'); -$config->project->search['params']['openedDate'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); -$config->project->search['params']['begin'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); -$config->project->search['params']['end'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); -$config->project->search['params']['realBegan'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); -$config->project->search['params']['realEnd'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); +$config->project->search['params']['openedDate'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); +$config->project->search['params']['begin'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); +$config->project->search['params']['end'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); +$config->project->search['params']['realBegan'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); +$config->project->search['params']['realEnd'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); $config->project->search['params']['openedBy'] = array('operator' => '=' , 'control' => 'select', 'values' => 'users'); $config->project->search['params']['closedBy'] = array('operator' => '=' , 'control' => 'select', 'values' => 'users'); -$config->project->search['params']['lastEditedDate'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); -$config->project->search['params']['closedDate'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date'); +$config->project->search['params']['lastEditedDate'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); +$config->project->search['params']['closedDate'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); $config->project->noSprintPriv['project'] = array('edit', 'group', 'createGroup', 'managePriv', 'manageMembers', 'manageGroupMember', 'copyGroup', 'editGroup', 'start', 'suspend', 'close', 'activate', 'delete', 'view', 'whitelist', 'addWhitelist', 'unbindWhitelist', 'manageProducts', 'dynamic', 'bug', 'testcase', 'testtask', 'testreport', 'team', 'unlinkMember'); $config->project->noSprintPriv['execution'] = array('task', 'grouptask', 'importplanstories', 'importBug', 'story', 'burn', 'computeBurn', 'fixFirst', 'burnData', 'linkStory', 'unlinkStory', 'batchUnlinkStory', 'updateOrder', 'taskKanban', 'printKanban', 'tree', 'treeTask', 'treeStory', 'storyKanban', 'storySort', 'storyEstimate', 'setKanban', 'storyView', 'calendar', 'effortCalendar', 'effort', 'taskEffort', 'computeTaskEffort', 'deleterelation', 'maintainrelation', 'relation', 'gantt', 'ganttsetting', 'ganttEdit'); diff --git a/module/release/config.php b/module/release/config.php index 45c3c2b251..6e2f4833f9 100644 --- a/module/release/config.php +++ b/module/release/config.php @@ -72,5 +72,5 @@ $config->release->search['params']['branch'] = array('operator' => '=', ' $config->release->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->release->search['params']['build'] = array('operator' => '=', 'control' => 'select', 'values' => array()); $config->release->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->release->statusList); -$config->release->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->release->search['params']['date'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->release->search['params']['marker'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->release->markerList); diff --git a/module/serverroom/config/search.php b/module/serverroom/config/search.php index 5cb9d3691e..e3272fde07 100644 --- a/module/serverroom/config/search.php +++ b/module/serverroom/config/search.php @@ -22,6 +22,6 @@ $config->serverroom->search['params']['bandwidth'] = array('operator' => 'incl $config->serverroom->search['params']['provider'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->serverroom->providerList); $config->serverroom->search['params']['owner'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->serverroom->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->serverroom->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->serverroom->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->serverroom->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->serverroom->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->serverroom->search['params']['editedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/stakeholder/config.php b/module/stakeholder/config.php index 30a3aae3e5..21fd97212b 100644 --- a/module/stakeholder/config.php +++ b/module/stakeholder/config.php @@ -25,4 +25,4 @@ $config->stakeholder->search['fields']['progress'] = $lang->stakeholder->prog $config->stakeholder->search['params']['expect'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); $config->stakeholder->search['params']['userID'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->stakeholder->search['params']['progress'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); -$config->stakeholder->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->stakeholder->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); diff --git a/module/testcase/config.php b/module/testcase/config.php index c16790b2a9..2293e1f3f1 100644 --- a/module/testcase/config.php +++ b/module/testcase/config.php @@ -83,9 +83,9 @@ $config->testcase->search['params']['lib'] = array('operator' => '=', $config->testcase->search['params']['lastRunner'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->testcase->search['params']['lastRunResult'] = array('operator' => '=', 'control' => 'select', 'values' => array_diff($lang->testcase->resultList, array('n/a' => $lang->testcase->resultList['n/a'])) + array('null' => $lang->testcase->unexecuted)); -$config->testcase->search['params']['lastRunDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->testcase->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->testcase->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->testcase->search['params']['lastRunDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->testcase->search['params']['openedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->testcase->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); global $app; $config->testcase->search['module'] = 'testcase'; diff --git a/module/zahost/config.php b/module/zahost/config.php index 6f970df3b4..eb22a29fe0 100644 --- a/module/zahost/config.php +++ b/module/zahost/config.php @@ -42,10 +42,10 @@ $config->zahost->search['params']['vsoft'] = array('operator' => '=', $config->zahost->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->zahost->statusList); $config->zahost->search['params']['instanceNum'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->zahost->search['params']['createdBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->zahost->search['params']['createdDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->zahost->search['params']['registerDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->zahost->search['params']['createdDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); +$config->zahost->search['params']['registerDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->zahost->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); -$config->zahost->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->zahost->search['params']['editedDate'] = array('operator' => '=', 'control' => 'date', 'values' => ''); $config->zahost->editor = new stdclass(); $config->zahost->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); From d3fd327650d3c428fc540f1ffda4df24ac39cbd9 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 11:19:06 +0800 Subject: [PATCH 204/235] * action: optimizer UI for searchForm. --- module/action/js/trash.ui.js | 13 +++++++++++++ module/action/ui/trash.html.php | 4 +--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 module/action/js/trash.ui.js diff --git a/module/action/js/trash.ui.js b/module/action/js/trash.ui.js new file mode 100644 index 0000000000..6e923ddf63 --- /dev/null +++ b/module/action/js/trash.ui.js @@ -0,0 +1,13 @@ +window.afterPageUpdate = function(target, info) +{ + if(info.name !== 'featureBar') return; + const $searchToggle = $(target).find('.search-form-toggle'); + if(!$searchToggle.length) + { + $searchToggle.closest('.show-search-form').removeClass('show-search-form'); + $('.search-form[data-module="trash"]').remove(); + return; + } + + if(!$searchToggle.parent().hasClass('active')) zui.updateSearchForm('trash'); +} diff --git a/module/action/ui/trash.html.php b/module/action/ui/trash.html.php index a1cdc7f52b..af19e89400 100644 --- a/module/action/ui/trash.html.php +++ b/module/action/ui/trash.html.php @@ -34,7 +34,7 @@ featureBar ( set::current($currentObjectType), set::linkParams("objectType={key}&type={$type}&byQuery=&queryID=&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"), - li(searchToggle(set::module('trash')), setClass($currentObjectType != 'all' ? '' : 'hidden', $byQuery ? 'active' : '')) + $currentObjectType != 'all' ? li(searchToggle(set::module('trash')), setClass($byQuery ? 'active' : '')) : null ); toolbar @@ -78,5 +78,3 @@ dtable set::userMap($users), set::footPager(usePager()) ); - -jsVar('window.afterPageUpdate', jsRaw("(target,info) => info.name === 'featureBar' && !$(target).find('.active>.search-form-toggle').length && zui.updateSearchForm('trash');")); From d128ada5eb4f238f62c79a275b90fda67f42fb20 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 20 Nov 2023 11:27:06 +0800 Subject: [PATCH 205/235] * Rewrite account module and add unit test. --- module/account/config.php | 2 +- module/account/control.php | 44 ++------------------------ module/account/model.php | 14 +------- module/account/test/model/getpairs.php | 21 ++++++++++++ module/common/model.php | 2 +- 5 files changed, 27 insertions(+), 56 deletions(-) create mode 100644 module/account/test/model/getpairs.php diff --git a/module/account/config.php b/module/account/config.php index e7aff3be43..46a33bf32e 100644 --- a/module/account/config.php +++ b/module/account/config.php @@ -7,4 +7,4 @@ $config->account->edit->requiredFields = 'name,account,provider'; $config->account->actions = new stdclass(); $config->account->actions->view = array(); -$config->account->actions->view['suffixActions'] = array('edit'); \ No newline at end of file +$config->account->actions->view['suffixActions'] = array('edit'); diff --git a/module/account/control.php b/module/account/control.php index 62860ac3f3..a57d321055 100644 --- a/module/account/control.php +++ b/module/account/control.php @@ -111,13 +111,10 @@ class account extends control * @access public * @return void */ - public function view($id) + public function view(int $id) { $this->view->title = $this->lang->account->view; - $this->view->position[] = html::a($this->createLink('account', 'browse'), $this->lang->account->common); - $this->view->position[] = $this->lang->account->view; - - $this->view->account = $this->account->getById($id); + $this->view->account = $this->account->getById($id); $this->view->rooms = $this->loadModel('serverroom')->getPairs(); $this->view->actions = $this->loadModel('action')->getList('account', $id); $this->view->users = $this->loadModel('user')->getPairs('noletter'); @@ -132,7 +129,7 @@ class account extends control * @access public * @return void */ - public function delete($id) + public function delete(int $id) { $this->account->delete(TABLE_ACCOUNT, $id); @@ -149,39 +146,4 @@ class account extends control } return $this->send($response); } - - /** - * Change account status. - * - * @param int $id - * @param int $accountID - * @param int $status - * @access public - * @return void - */ - public function changeStatus($id, $accountID, $status) - { - $accountStatus = $status == 'offline' ? 'online' : 'offline'; - if($_SERVER['REQUEST_METHOD'] == 'POST') - { - $postData = fixer::input('post')->get(); - if(empty($postData->reason)) - { - $reasonKey = $accountStatus . 'Reason'; - $errTip = $this->lang->account->{$reasonKey}; - dao::$errors['submit'][] = sprintf($this->lang->error->notempty, $errTip); - return print(js::error(dao::getError())); - } - - $this->account->updateStatus($accountID, $accountStatus); - - $this->loadModel('action')->create('account', $id, $accountStatus, $postData->reason); - if(isInModal()) return print(js::reload('parent.parent')); - return print(js::reload('parent')); - } - - $this->view->title = $this->lang->account->{$accountStatus}; - $this->display(); - } - } diff --git a/module/account/model.php b/module/account/model.php index a922390244..58ced2771a 100644 --- a/module/account/model.php +++ b/module/account/model.php @@ -23,18 +23,6 @@ class accountModel extends model return $this->dao->select('*')->from(TABLE_ACCOUNT)->where('id')->eq($id)->fetch(); } - /** - * Get accounts by id list. - * - * @param int $idList - * @access public - * @return array - */ - public function getByIdList($idList) - { - return $this->dao->select('*')->from(TABLE_ACCOUNT)->where('id')->in($idList)->fetchAll('id'); - } - /** * Get account list. * @@ -83,7 +71,7 @@ class accountModel extends model * @access public * @return array */ - public function getPairs() + public function getPairs(): array { return $this->dao->select('id,name')->from(TABLE_ACCOUNT)->where('deleted')->eq('0')->fetchPairs(); } diff --git a/module/account/test/model/getpairs.php b/module/account/test/model/getpairs.php new file mode 100644 index 0000000000..1d21ba692d --- /dev/null +++ b/module/account/test/model/getpairs.php @@ -0,0 +1,21 @@ +#!/usr/bin/env php +gen(10); + +/** + +title=accountModel->getList(); +timeout=0 +cid=1 + +*/ + +global $tester; +$accountModel = $tester->loadModel('account'); +$pairs = $accountModel->getPairs(); +r(count($pairs)) && p() && e('10'); // 检查获取数据数。 +r($pairs) && p('1,2') && e('运维账号1,运维账号2'); // 检查部分数据。 diff --git a/module/common/model.php b/module/common/model.php index 6926650b98..32ad3a0762 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -3847,7 +3847,7 @@ EOT; if(!common::hasPriv($moduleName, $action)) continue; } - if(false === $this->{$moduleName}->isClickable($data, $action)) continue; + if(method_exists($this->{$moduleName}, 'isClickable') && false === $this->{$moduleName}->isClickable($data, $action)) continue; if($menu == 'suffixActions' && !empty($actionData['text']) && empty($actionData['showText'])) $actionData['text'] = ''; From 7a67aa7ce51074e008c85bbfeea2a9ac6b8a178e Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 12:10:37 +0800 Subject: [PATCH 206/235] * gitlab: reset formdata on render dtable. --- module/gitlab/js/binduser.ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/gitlab/js/binduser.ui.js b/module/gitlab/js/binduser.ui.js index 338097a421..15225a2286 100644 --- a/module/gitlab/js/binduser.ui.js +++ b/module/gitlab/js/binduser.ui.js @@ -44,6 +44,6 @@ window.onPageRender = function(info) const dtable = zui.DTable.query('#table-gitlab-binduser'); /* Clear saved formData. */ - if(dtable) dtable.$.data.formData = {}; + if(dtable) dtable.$.resetFormData(); } }; From 93db149f083f27cf068d924c35f04c30bffd633f Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 13:33:58 +0800 Subject: [PATCH 207/235] * Adjust label style of the product view page. --- module/product/ui/view.html.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/product/ui/view.html.php b/module/product/ui/view.html.php index 3520a0251c..e3c0851c6f 100644 --- a/module/product/ui/view.html.php +++ b/module/product/ui/view.html.php @@ -137,17 +137,17 @@ div ), !$hiddenCode ? label ( - setClass('light-outline mx-2 flex-none'), + setClass('light-outline ml-2 flex-none'), $product->code ) : null, $product->type != 'normal' ? label ( - setClass('light-outline mx-2 text-warning flex-none'), + setClass('light-outline ml-2 text-warning flex-none'), $lang->product->typeList[$product->type] ) : null, $product->deleted ? label ( - setClass('danger-outline text-dange flex-noner'), + setClass('danger-outline text-dange flex-noner ml-2'), $lang->product->deleted ) : null, label From f1e1a545698b71c2dac5f2b2ccb61e91b05245fe Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 13:40:11 +0800 Subject: [PATCH 208/235] * Hide product drop menu if no product. --- lib/zin/wg/dropmenu/v1.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/zin/wg/dropmenu/v1.php b/lib/zin/wg/dropmenu/v1.php index a0c97eeaae..ab99b05cdb 100644 --- a/lib/zin/wg/dropmenu/v1.php +++ b/lib/zin/wg/dropmenu/v1.php @@ -76,6 +76,7 @@ class dropmenu extends wg $object = data($tab); if(isset($object->id)) $objectID = $object->id; } + if($method == 'showerrornone' && empty($object) && empty($objectID)) return array(); if($module == 'testcase' && $method == 'view' && data('isLibCase')) $tab = 'caselib'; From 91bf4d6026caaaf6f8b988043799018752879421 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Mon, 20 Nov 2023 13:43:17 +0800 Subject: [PATCH 209/235] * Add required item for edit bug. --- lib/zin/wg/tabledata/css/v1.css | 3 ++- lib/zin/wg/tabledata/v1.php | 6 ++++-- module/bug/ui/edit.html.php | 11 +++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/zin/wg/tabledata/css/v1.css b/lib/zin/wg/tabledata/css/v1.css index cbfb539c83..2119e915dc 100644 --- a/lib/zin/wg/tabledata/css/v1.css +++ b/lib/zin/wg/tabledata/css/v1.css @@ -1,3 +1,4 @@ .table-data {table-layout: fixed;} .table-data th, -.table-data .table-data-th {width: 60px; color: var(--color-slate-600);} +.table-data .table-data-th {width: 65px; color: var(--color-slate-600);} +.table-data th.required:before {content: '*'; color: rgba(var(--color-danger-500-rgb),var(--tw-text-opacity)); position: relative; top: 0.25rem; right: 0.25rem;} diff --git a/lib/zin/wg/tabledata/v1.php b/lib/zin/wg/tabledata/v1.php index a173e15f64..4859449f7d 100644 --- a/lib/zin/wg/tabledata/v1.php +++ b/lib/zin/wg/tabledata/v1.php @@ -12,7 +12,8 @@ class tableData extends wg protected static array $defineProps = array( 'title?: string', 'useTable?: bool=true', - 'class?: string' + 'class?: string', + 'required?: bool=false' ); public static function getPageCSS(): string|false @@ -22,12 +23,13 @@ class tableData extends wg private function buildItemWithTr($item): wg { + $required = $item->prop('required'); return h::tr ( setClass($item->prop('trClass')), h::th ( - setClass('py-1.5 pr-2 font-normal nowrap text-right', $item->prop('thClass')), + setClass('py-1.5 pr-2 font-normal nowrap text-right' . ($required ? ' required' : ''), $item->prop('thClass')), $item->prop('name'), $item->block('suffixName') ), diff --git a/module/bug/ui/edit.html.php b/module/bug/ui/edit.html.php index 46fc984ae4..eb05d25a93 100644 --- a/module/bug/ui/edit.html.php +++ b/module/bug/ui/edit.html.php @@ -79,6 +79,7 @@ detailBody section ( set::title($lang->bug->legendSteps), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',steps,') !== false), editor ( set::name('steps'), @@ -165,6 +166,7 @@ detailBody ( set::trClass($product->shadow && isset($project) && empty($project->multiple) ? 'hidden' : ''), set::name($lang->bug->plan), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',plan,') !== false), formGroup ( set('id', 'planBox'), @@ -193,6 +195,7 @@ detailBody item ( set::name($lang->bug->type), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',type,') !== false), formGroup ( picker @@ -206,6 +209,7 @@ detailBody item ( set::name($lang->bug->severity), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',severity,') !== false), severityPicker ( set::items($lang->bug->severityList), @@ -217,6 +221,7 @@ detailBody item ( set::name($lang->bug->pri), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',pri,') !== false), priPicker ( set::items($lang->bug->priList), @@ -248,6 +253,7 @@ detailBody item ( set::name($lang->bug->assignedTo), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',assignedTo,') !== false), formGroup ( inputGroup @@ -275,6 +281,7 @@ detailBody item ( set::name($lang->bug->deadline), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',deadline,') !== false), formGroup ( datePicker @@ -305,6 +312,7 @@ detailBody item ( set::name($lang->bug->os), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',os,') !== false), formGroup ( picker @@ -319,6 +327,7 @@ detailBody item ( set::name($lang->bug->browser), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',browser,') !== false), formGroup ( picker @@ -333,6 +342,7 @@ detailBody item ( set::name($lang->bug->keywords), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',keywords,') !== false), formGroup ( input @@ -397,6 +407,7 @@ detailBody item ( set::name($lang->bug->project), + set::required(strpos(",{$config->bug->edit->requiredFields},", ',project,') !== false), formGroup ( set('id', 'projectBox'), From 8f93d3d8305b6c4a2ae480ca06d388a748231b3d Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 13:45:42 +0800 Subject: [PATCH 210/235] * Corrent the lang of story create page. --- module/story/ui/create.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/story/ui/create.html.php b/module/story/ui/create.html.php index 8d571d30e4..ea3fb99c69 100644 --- a/module/story/ui/create.html.php +++ b/module/story/ui/create.html.php @@ -272,7 +272,7 @@ formPanel inputGroup ( span(setClass('URSBox'), picker(setID('URS'), set::name('URS[]'), set::items($fields['URS']['options']), set::value($fields['URS']['default']))), - btn(setData(array('on' => 'click', 'call' => 'loadURS', 'params' => 'allURS')), $lang->story->loadMyStories) + btn(setData(array('on' => 'click', 'call' => 'loadURS', 'params' => 'allURS')), $lang->story->loadAllStories) ) ), formGroup From 6953a14933cc1ae04bb3f9309ad6015c189c1b5e Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 13:50:12 +0800 Subject: [PATCH 211/235] * Fix bug, replace `array()` with `[]`. --- lib/zin/wg/formsettingbtn/js/v1.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/zin/wg/formsettingbtn/js/v1.js b/lib/zin/wg/formsettingbtn/js/v1.js index ca112e407b..99d25ffa8b 100644 --- a/lib/zin/wg/formsettingbtn/js/v1.js +++ b/lib/zin/wg/formsettingbtn/js/v1.js @@ -39,8 +39,8 @@ function revertDefaultFields(e) function onSubmitFormtSetting(e) { - const customFields = array(); - const showFields = array(); + const customFields = []; + const showFields = []; const $form = $(e.target).closest('form'); $.post($form.attr('action'), new FormData($form[0]), function(result) @@ -124,8 +124,8 @@ function toggleBatchField(customFields, showFields) { if(typeof customFields == 'undefined') return false; - let hiddenFields = array(); - let shownFields = array(); + let hiddenFields = []; + let shownFields = []; customFields.forEach(function(field) { if($('th.form-batch-head[data-name="' + field + '"]').length == 0) return true; From 98ef5b37ff54e9a9addcbba68b5a57b37bd0b45b Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 13:54:02 +0800 Subject: [PATCH 212/235] * zin: fix afterPageUpdate not work with loadComponent. --- www/js/zui3/zin.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/www/js/zui3/zin.js b/www/js/zui3/zin.js index e0aba80c7e..01664a2603 100644 --- a/www/js/zui3/zin.js +++ b/www/js/zui3/zin.js @@ -325,7 +325,12 @@ const props = info.data.props; if(typeof props !== 'object') return; const component = $target.zui(info.name); - if(typeof component === 'object' && typeof component.render === 'function') component.render(props); + if(typeof component === 'object' && typeof component.render === 'function') + { + beforeUpdate($target, info, options); + component.render(props); + afterUpdate($target, info, options); + } return; } From 448e39e85ed392519f86cc244e2b2830f0e08629 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 20 Nov 2023 13:54:21 +0800 Subject: [PATCH 213/235] * gitlab: fix form not update on reload dtable. --- module/gitlab/js/binduser.ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/gitlab/js/binduser.ui.js b/module/gitlab/js/binduser.ui.js index 15225a2286..8c082f3913 100644 --- a/module/gitlab/js/binduser.ui.js +++ b/module/gitlab/js/binduser.ui.js @@ -37,7 +37,7 @@ window.bindUser = function(e) }); } -window.onPageRender = function(info) +window.afterPageUpdate = function($target, info) { if(info.name === 'dtable') { From 840c3599cc31243dc8ed6ed395ccddfdd58ac2be Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 13:55:25 +0800 Subject: [PATCH 214/235] * Fixed the bug of story edit page. --- module/story/ui/edit.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/story/ui/edit.html.php b/module/story/ui/edit.html.php index 4b0e68c831..4b8c4dfc53 100644 --- a/module/story/ui/edit.html.php +++ b/module/story/ui/edit.html.php @@ -257,7 +257,7 @@ detailBody span ( setID('planIdBox'), - picker(setID('plan'), set::name($multiplePlan ? 'plan[]' : 'plan'), set::items($fields['plan']['options']), set::value($fields['parent']['default']), set::multiple($multiplePlan)), + picker(setID('plan'), set::name($multiplePlan ? 'plan[]' : 'plan'), set::items($fields['plan']['options']), set::value($fields['plan']['default']), set::multiple($multiplePlan)), ), empty($plans) ? btn(set::url($this->createLink('productplan', 'create', "productID={$story->product}&branch={$story->branch}")), setData(array('toggle' => 'modal')), icon('plus')) : null, empty($plans) ? btn(set('onclick', "loadProductPlans({$story->product})"), setClass('refresh'), icon('refresh')) : null From bf8240bc66f749241fce984abfe153197cba7594 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 13:59:45 +0800 Subject: [PATCH 215/235] * Fix form not update on reload dtable. --- module/gitea/js/binduser.ui.js | 11 +++++++++++ module/gogs/js/binduser.ui.js | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/module/gitea/js/binduser.ui.js b/module/gitea/js/binduser.ui.js index 6969aa7757..48e4d20828 100644 --- a/module/gitea/js/binduser.ui.js +++ b/module/gitea/js/binduser.ui.js @@ -36,3 +36,14 @@ window.bindUser = function(e) data: postData }); } + +window.afterPageUpdate = function($target, info) +{ + if(info.name === 'dtable') + { + const dtable = zui.DTable.query('#table-gitea-binduser'); + + /* Clear saved formData. */ + if(dtable) dtable.$.resetFormData(); + } +}; diff --git a/module/gogs/js/binduser.ui.js b/module/gogs/js/binduser.ui.js index ef7fe61dc9..deb69a6c31 100644 --- a/module/gogs/js/binduser.ui.js +++ b/module/gogs/js/binduser.ui.js @@ -36,3 +36,14 @@ window.bindUser = function(e) data: postData }); } + +window.afterPageUpdate = function($target, info) +{ + if(info.name === 'dtable') + { + const dtable = zui.DTable.query('#table-gogs-binduser'); + + /* Clear saved formData. */ + if(dtable) dtable.$.resetFormData(); + } +}; From 27d8244fd40999c63ba7b2311273203c3a4b0509 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 20 Nov 2023 13:58:05 +0800 Subject: [PATCH 216/235] * Adjust task kanban height and fix undefind parent field error. --- module/execution/ui/taskkanban.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/execution/ui/taskkanban.html.php b/module/execution/ui/taskkanban.html.php index 867de33985..d7d4299704 100644 --- a/module/execution/ui/taskkanban.html.php +++ b/module/execution/ui/taskkanban.html.php @@ -32,7 +32,7 @@ foreach($kanbanGroup as $index => $group) foreach($group['data']['cols'] as $colIndex => $col) { $colPairs[$col['id']] = $col['type']; - if($col['parent'] != '-1') $groupCols[$groupID][$col['id']] = $col['title']; + if(isset($col['parent']) && $col['parent'] != '-1') $groupCols[$groupID][$col['id']] = $col['title']; } $kanbanGroup[$index] = $group; @@ -229,7 +229,7 @@ div ( set::key('kanban'), set::items($kanbanGroup), - set::height('calc(100vh - 80px)') + set::height('calc(100vh - 120px)') ) ); From f120d4aeac46b3465b5ec7602796ef364508bb6b Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 14:02:12 +0800 Subject: [PATCH 217/235] + Add variable inited. --- module/mr/config.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/module/mr/config.php b/module/mr/config.php index e4e1563cd7..6d90f2619b 100644 --- a/module/mr/config.php +++ b/module/mr/config.php @@ -36,26 +36,32 @@ $config->mrapproval->create->requiredFields = 'mrID,account,date,action'; $config->mr->gitServiceList = array('gitlab', 'gitea', 'gogs'); +$config->mr->actionList = array(); +$config->mr->actionList['view'] = array(); $config->mr->actionList['view']['icon'] = 'eye'; $config->mr->actionList['view']['hint'] = $lang->mr->view; $config->mr->actionList['view']['url'] = helper::createLink('mr', 'view', "MRID={id}"); $config->mr->actionList['view']['data-app'] = $app->tab; +$config->mr->actionList['edit'] = array(); $config->mr->actionList['edit']['icon'] = 'edit'; $config->mr->actionList['edit']['hint'] = $lang->mr->edit; $config->mr->actionList['edit']['url'] = helper::createLink('mr', 'edit', "MRID={id}"); $config->mr->actionList['edit']['data-app'] = $app->tab; +$config->mr->actionList['diff'] = array(); $config->mr->actionList['diff']['icon'] = 'diff'; $config->mr->actionList['diff']['hint'] = $lang->mr->diff; $config->mr->actionList['diff']['url'] = helper::createLink('mr', 'diff', "MRID={id}"); $config->mr->actionList['diff']['data-app'] = $app->tab; +$config->mr->actionList['link'] = array(); $config->mr->actionList['link']['icon'] = 'link'; $config->mr->actionList['link']['hint'] = $lang->mr->link; $config->mr->actionList['link']['url'] = helper::createLink('mr', 'link', "MRID={id}"); $config->mr->actionList['link']['data-app'] = $app->tab; +$config->mr->actionList['delete'] = array(); $config->mr->actionList['delete']['icon'] = 'trash'; $config->mr->actionList['delete']['hint'] = $lang->mr->delete; $config->mr->actionList['delete']['url'] = helper::createLink('mr', 'delete', "MRID={id}"); @@ -63,29 +69,34 @@ $config->mr->actionList['delete']['data-confirm'] = $lang->mr->confirmDelete; $config->mr->actionList['delete']['className'] = 'ajax-submit'; $config->mr->actionList['delete']['data-app'] = $app->tab; +$config->mr->actionList['accept'] = array(); $config->mr->actionList['accept']['icon'] = 'flow'; $config->mr->actionList['accept']['text'] = $lang->mr->acceptMR; $config->mr->actionList['accept']['url'] = helper::createLink('mr', 'accept', "MRID={id}"); $config->mr->actionList['accept']['data-app'] = $app->tab; +$config->mr->actionList['approval'] = array(); $config->mr->actionList['approval']['icon'] = 'ok'; $config->mr->actionList['approval']['text'] = $lang->mr->approve; $config->mr->actionList['approval']['url'] = helper::createLink('mr', 'approval', "MRID={id}&action=approve"); $config->mr->actionList['approval']['data-toggle'] = 'modal'; $config->mr->actionList['approval']['data-app'] = $app->tab; +$config->mr->actionList['reject'] = array(); $config->mr->actionList['reject']['icon'] = 'bug'; $config->mr->actionList['reject']['text'] = $lang->mr->reject; $config->mr->actionList['reject']['url'] = helper::createLink('mr', 'approval', "MRID={id}&action=reject"); $config->mr->actionList['reject']['data-toggle'] = 'modal'; $config->mr->actionList['reject']['data-app'] = $app->tab; +$config->mr->actionList['close'] = array(); $config->mr->actionList['close']['icon'] = 'off'; $config->mr->actionList['close']['text'] = $lang->mr->close; $config->mr->actionList['close']['url'] = helper::createLink('mr', 'close', "MRID={id}"); $config->mr->actionList['close']['className'] = 'ajax-submit'; $config->mr->actionList['close']['data-app'] = $app->tab; +$config->mr->actionList['reopen'] = array(); $config->mr->actionList['reopen']['icon'] = 'restart'; $config->mr->actionList['reopen']['text'] = $lang->mr->reopen; $config->mr->actionList['reopen']['url'] = helper::createLink('mr', 'reopen', "MRID={id}"); @@ -97,10 +108,12 @@ $app->loadLang('story'); $app->loadLang('bug'); $app->loadLang('build'); $app->loadLang('task'); +$config->mr->actionList['unlinkStory'] = array(); $config->mr->actionList['unlinkStory']['icon'] = 'unlink'; $config->mr->actionList['unlinkStory']['hint'] = $lang->release->unlinkStory; $config->mr->actionList['unlinkStory']['url'] = 'javascript: unlinkObject("story", "{id}")'; +$config->mr->actionList['unlinkBug'] = array(); $config->mr->actionList['unlinkBug']['icon'] = 'unlink'; $config->mr->actionList['unlinkBug']['hint'] = $lang->release->unlinkBug; $config->mr->actionList['unlinkBug']['url'] = 'javascript: unlinkObject("bug", "{id}")'; From ea119126897288c003a3b93cb9c21320038f6ca8 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 20 Nov 2023 14:02:23 +0800 Subject: [PATCH 218/235] + Add function param type. --- module/repo/control.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/repo/control.php b/module/repo/control.php index 5d71129b13..9de6afb466 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -316,7 +316,7 @@ class repo extends control * @access public * @return void */ - public function monaco($repoID, $objectID = 0, $entry = '', $revision = 'HEAD', $showBug = 'false', $encoding = '') + public function monaco(int $repoID, int $objectID = 0, string $entry = '', string $revision = 'HEAD', string $showBug = 'false', string $encoding = '') { $this->commonAction($repoID, $objectID); @@ -356,7 +356,7 @@ class repo extends control * @access public * @return void */ - public function view($repoID, $objectID = 0, $entry = '', $revision = 'HEAD', $showBug = 'false', $encoding = '') + public function view(int $repoID, int $objectID = 0, string $entry = '', string $revision = 'HEAD', string $showBug = 'false', string $encoding = '') { set_time_limit(0); if($this->get->repoPath) $entry = $this->get->repoPath; From ac2966939622b9586efd4cd085ec16f5222cf1ac Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 14:04:12 +0800 Subject: [PATCH 219/235] * Fix bug, load product model. --- module/execution/zen.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/zen.php b/module/execution/zen.php index 1d1e73b03e..f724d59c64 100644 --- a/module/execution/zen.php +++ b/module/execution/zen.php @@ -404,7 +404,7 @@ class executionZen extends execution $this->view->title = $this->lang->execution->testcase; $this->view->executionID = $executionID; $this->view->productID = $productID; - $this->view->product = $this->product->getByID((int) $productID); + $this->view->product = $this->loadModel('product')->getByID((int)$productID); $this->view->orderBy = $orderBy; $this->view->pager = $pager; $this->view->type = $type; From 03301c87bf2e8cb21135e357b219254b6447e9fb Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 20 Nov 2023 14:05:03 +0800 Subject: [PATCH 220/235] * project: adjust lang items for frontend. --- module/project/lang/de.php | 4 ++-- module/project/lang/en.php | 4 ++-- module/project/lang/fr.php | 4 ++-- module/project/lang/zh-cn.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/module/project/lang/de.php b/module/project/lang/de.php index 1b6c0b5fed..df819c1629 100644 --- a/module/project/lang/de.php +++ b/module/project/lang/de.php @@ -419,8 +419,8 @@ $lang->project->cannotCancelCat = "There are child {$lang->projectCommon}s $lang->project->parentBeginEnd = "The begin and end date of the parent {$lang->projectCommon}: %s ~ %s"; $lang->project->parentBudget = "The budget of the parent program: "; -$lang->project->beginLessThanParent = "The start date of the {$lang->projectCommon} is < the start date of the parent program:"; -$lang->project->endGreatThanParent = "The finish date of the {$lang->projectCommon} is > the finish date of the parent program:"; +$lang->project->beginLessThanParent = "The start date of the {$lang->projectCommon} is < the start date of the parent program: . "; +$lang->project->endGreatThanParent = "The finish date of the {$lang->projectCommon} is > the finish date of the parent program: . "; $lang->project->dateExceedParent = "The start and finish date of the {$lang->projectCommon} was > the start and finish date of the parent program:"; $lang->project->beginGreatEqualChild = "The start date of the {$lang->projectCommon} should be ≥ the start date of program: %s."; $lang->project->endLessThanChild = "The finish date of the {$lang->projectCommon} should be ≤ the finish date of program: %s."; diff --git a/module/project/lang/en.php b/module/project/lang/en.php index 243cc4f6ac..78595144c9 100644 --- a/module/project/lang/en.php +++ b/module/project/lang/en.php @@ -423,8 +423,8 @@ $lang->project->cannotCancelCat = "There are child {$lang->projectCommon}s $lang->project->parentBeginEnd = "The begin and end date of the parent {$lang->projectCommon}: %s ~ %s"; $lang->project->parentBudget = "The budget of the parent program: "; -$lang->project->beginLessThanParent = "The start date of the {$lang->projectCommon} is < the start date of the parent program:"; -$lang->project->endGreatThanParent = "The finish date of the {$lang->projectCommon} is > the finish date of the parent program:"; +$lang->project->beginLessThanParent = "The start date of the {$lang->projectCommon} is < the start date of the parent program: . "; +$lang->project->endGreatThanParent = "The finish date of the {$lang->projectCommon} is > the finish date of the parent program: . "; $lang->project->dateExceedParent = "The start and finish date of the {$lang->projectCommon} was > the start and finish date of the parent program:"; $lang->project->beginGreatEqualChild = "The start date of the {$lang->projectCommon} should be ≥ the start date of program: %s."; $lang->project->endLessThanChild = "The finish date of the {$lang->projectCommon} should be ≤ the finish date of program: %s."; diff --git a/module/project/lang/fr.php b/module/project/lang/fr.php index 1b6c0b5fed..df819c1629 100644 --- a/module/project/lang/fr.php +++ b/module/project/lang/fr.php @@ -419,8 +419,8 @@ $lang->project->cannotCancelCat = "There are child {$lang->projectCommon}s $lang->project->parentBeginEnd = "The begin and end date of the parent {$lang->projectCommon}: %s ~ %s"; $lang->project->parentBudget = "The budget of the parent program: "; -$lang->project->beginLessThanParent = "The start date of the {$lang->projectCommon} is < the start date of the parent program:"; -$lang->project->endGreatThanParent = "The finish date of the {$lang->projectCommon} is > the finish date of the parent program:"; +$lang->project->beginLessThanParent = "The start date of the {$lang->projectCommon} is < the start date of the parent program: . "; +$lang->project->endGreatThanParent = "The finish date of the {$lang->projectCommon} is > the finish date of the parent program: . "; $lang->project->dateExceedParent = "The start and finish date of the {$lang->projectCommon} was > the start and finish date of the parent program:"; $lang->project->beginGreatEqualChild = "The start date of the {$lang->projectCommon} should be ≥ the start date of program: %s."; $lang->project->endLessThanChild = "The finish date of the {$lang->projectCommon} should be ≤ the finish date of program: %s."; diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php index 4a3ff7b05d..a8bb03385d 100644 --- a/module/project/lang/zh-cn.php +++ b/module/project/lang/zh-cn.php @@ -423,8 +423,8 @@ $lang->project->cannotCancelCat = "该{$lang->projectCommon}下已经有子 $lang->project->parentBeginEnd = "父{$lang->projectCommon}起止时间:%s ~ %s"; $lang->project->parentBudget = "父项目集预算:"; -$lang->project->beginLessThanParent = "{$lang->projectCommon}的开始日期小于了父项目集的开始日期:"; -$lang->project->endGreatThanParent = "{$lang->projectCommon}的完成日期大于了父项目集的完成日期:"; +$lang->project->beginLessThanParent = "{$lang->projectCommon}的开始日期小于了父项目集的开始日期:。"; +$lang->project->endGreatThanParent = "{$lang->projectCommon}的完成日期大于了父项目集的完成日期:。"; $lang->project->dateExceedParent = "{$lang->projectCommon}的起止日期已超出父项目集的起止日期:"; $lang->project->beginGreatEqualChild = "{$lang->projectCommon}的开始日期应大于等于项目集的最小开始日期:%s"; $lang->project->endLessThanChild = "{$lang->projectCommon}的完成日期应小于等于项目集的最大完成日期:%s"; From 8917c6c19ed3715f103e648bcd391280e87bf17c Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 20 Nov 2023 14:05:53 +0800 Subject: [PATCH 221/235] + project: add date tip and bind event when change the parent, begin and end field. --- module/project/ui/create.html.php | 13 +++++++++++++ module/project/ui/edit.html.php | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 58b8014eb0..6e06f97698 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -163,6 +163,7 @@ formPanel on::change('[name=multiple]', 'toggleMultiple'), on::change('[name=future]', 'toggleBudget'), on::change('[name=newProduct]', 'addProduct'), + $config->systemMode != 'light' ? on::change('#begin, #end, #parent', 'checkDate') : null, formRow ( formGroup @@ -342,6 +343,18 @@ formPanel ) ) ), + formRow + ( + setID('dateTip'), + setClass('hidden'), + formGroup + ( + set::label(''), + span(setID('beginLess'), setClass('text-warning hidden'), html($lang->project->beginLessThanParent)), + span(setID('endGreater'), setClass('text-warning hidden'), html($lang->project->endGreatThanParent)), + a(setClass('underline text-warning'), set::href('javascript:;'), on::click("ignoreTip('dateTip')"), $lang->project->ignore) + ) + ), formGroup ( set::label($lang->project->days), diff --git a/module/project/ui/edit.html.php b/module/project/ui/edit.html.php index 5df38fefb6..9693101acc 100644 --- a/module/project/ui/edit.html.php +++ b/module/project/ui/edit.html.php @@ -176,6 +176,7 @@ formPanel on::change('#parent', 'setParentProgram'), on::change('#begin, [name=delta]', 'computeEndDate'), on::change('#begin, #end', 'computeWorkDays'), + on::change('#begin, #end, #parent', 'checkDate'), on::change('[name^=products]', 'productChange'), on::change('[name^=branch]', 'branchChange'), on::change('[name=future]', 'toggleBudget'), @@ -358,6 +359,18 @@ formPanel ) ), formRow + ( + setID('dateTip'), + setClass('hidden'), + formGroup + ( + set::label(''), + span(setID('beginLess'), setClass('text-warning hidden'), html($lang->project->beginLessThanParent)), + span(setID('endGreater'), setClass('text-warning hidden'), html($lang->project->endGreatThanParent)), + a(setClass('underline text-warning'), set::href('javascript:;'), on::click("ignoreTip('dateTip')"), $lang->project->ignore) + ) + ), + formRow ( setClass($delta == 999 ? 'hidden' : ''), formGroup From 1f8700e53e6e2d6f7a8ea27d70d35cf0cd143d27 Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 20 Nov 2023 14:06:55 +0800 Subject: [PATCH 222/235] + project: add date tip template and bind event when change parent, begin and end field. --- module/project/ui/batchedit.html.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/module/project/ui/batchedit.html.php b/module/project/ui/batchedit.html.php index 78a8b6edd0..1ae5a280b6 100644 --- a/module/project/ui/batchedit.html.php +++ b/module/project/ui/batchedit.html.php @@ -28,6 +28,7 @@ formBatchPanel set::data(array_values($projects)), set::onRenderRow(jsRaw('renderRowData')), on::change('[name^=begin],[name^=end]', 'batchComputeWorkDays'), + $config->systemMode != 'light' ? on::change('[name^=begin],[name^=end],[name^=parent]', 'batchCheckDate') : null, formBatchItem ( set::name('id'), @@ -111,4 +112,25 @@ formBatchPanel ) ); +h::table +( + setID('dateTipTemplate'), + setClass('hidden'), + h::tr + ( + setClass('dateTip'), + h::td + ( + set::colspan(9), + div + ( + setClass('text-right'), + span(setClass('beginLess text-warning hidden'), html($lang->project->beginLessThanParent)), + span(setClass('endGreater text-warning hidden'), html($lang->project->endGreatThanParent)), + a(setClass('underline text-warning'), set::href('javascript:;'), $lang->project->ignore) + ) + ) + ) +); + render(); From fe852df08a65f677c6a226d147c9d36bf757873f Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 14:07:31 +0800 Subject: [PATCH 223/235] * Remove prefix of executions. --- module/execution/control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/control.php b/module/execution/control.php index e086f875b3..3bf371e8c1 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -44,7 +44,7 @@ class execution extends control $mode = $this->app->tab == 'execution' ? 'multiple' : ''; if((defined('RUN_MODE') and RUN_MODE == 'api') or $this->viewType == 'json') $mode = ''; - $this->executions = $this->execution->getPairs(0, 'all', "nocode,{$mode}"); + $this->executions = $this->execution->getPairs(0, 'all', "nocode,noprefix,{$mode}"); $skipCreateStep = array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers', 'all', 'ajaxgetcopyprojectexecutions'); if(in_array($this->methodName, $skipCreateStep) && $this->app->tab == 'execution') return false; if($this->executions || $this->methodName == 'index' || $this->methodName == 'create' || $this->app->getViewType() == 'mhtml') return false; From 2e0d819eac7f5e850c959928fc4425e15b7e4bef Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 20 Nov 2023 14:08:35 +0800 Subject: [PATCH 224/235] * project: simplify function to check days. --- module/project/js/batchedit.ui.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/project/js/batchedit.ui.js b/module/project/js/batchedit.ui.js index 299733a508..bfd8106aac 100644 --- a/module/project/js/batchedit.ui.js +++ b/module/project/js/batchedit.ui.js @@ -7,12 +7,12 @@ */ function batchComputeWorkDays() { - if($(this).closest('tr').find('div[data-longtime="1"]').length > 0) return false; + const $tr = $(this).closest('tr'); + if($tr.find('div[data-longtime="1"]').length > 0) return false; - const index = $(this).attr('name').replace(/(begin\[)|(end\[)|(\])/g, ''); - const beginDate = $('[name=begin\\[' + index + '\\]').val(); - const endDate = $('[name=end\\[' + index + '\\]').val(); - $('[name=days\\[' + index + '\\]').val(computeDaysDelta(beginDate, endDate)); + const beginDate = $tr.find('[name^=begin]').val(); + const endDate = $tr.find('[name^=end]').val(); + $tr.find('[name^=days]').val(computeDaysDelta(beginDate, endDate)); } window.renderRowData = function($row, index, row) From 0c7cb25110317a6fd147174f4d04dc42cf7af8df Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Mon, 20 Nov 2023 14:08:39 +0800 Subject: [PATCH 225/235] * Add required icon for product. --- module/product/model.php | 1 + module/product/tao.php | 1 + module/product/zen.php | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/module/product/model.php b/module/product/model.php index 85204634af..3985e7b5eb 100755 --- a/module/product/model.php +++ b/module/product/model.php @@ -352,6 +352,7 @@ class productModel extends model $this->dao->insert(TABLE_PRODUCT)->data($product)->autoCheck() ->checkIF(!empty($product->name), 'name', 'unique', "`program` = {$product->program} AND `deleted` = '0'") ->checkIF(!empty($product->code), 'code', 'unique', "`deleted` = '0'") + ->batchCheck($this->config->product->create->requiredFields, 'notempty') ->checkFlow() ->exec(); if(dao::isError()) return false; diff --git a/module/product/tao.php b/module/product/tao.php index 4b1473140a..187567e512 100644 --- a/module/product/tao.php +++ b/module/product/tao.php @@ -405,6 +405,7 @@ class productTao extends productModel $this->dao->update(TABLE_PRODUCT)->data($product)->autoCheck() ->checkIF(!empty($product->name), 'name', 'unique', "id != {$productID} and `program` = {$programID} and `deleted` = '0'") ->checkIF(!empty($product->code), 'code', 'unique', "id != {$productID} and `deleted` = '0'") + ->batchCheck($this->config->product->edit->requiredFields, 'notempty') ->checkFlow() ->where('id')->eq($productID) ->exec(); diff --git a/module/product/zen.php b/module/product/zen.php index ffa9b85d43..9130e595d0 100644 --- a/module/product/zen.php +++ b/module/product/zen.php @@ -269,6 +269,12 @@ class productZen extends product $fields = $this->setSelectFormOptions($programID, $this->config->product->form->create); $fields['program']['default'] = $programID; + /* Set required. */ + foreach($fields as $field => $attr) + { + if(strpos(",{$this->config->product->create->requiredFields},", ",$field,") !== false) $fields[$field]['required'] = true; + } + return $fields; } @@ -300,6 +306,7 @@ class productZen extends product foreach($fields as $field => $attr) { if(isset($product->{$field})) $fields[$field]['default'] = $product->{$field}; + if(strpos(",{$this->config->product->edit->requiredFields},", ",$field,") !== false) $fields[$field]['required'] = true; } return $fields; From 0557257e9bba623bd8768e9d42c1188a044cabb9 Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 20 Nov 2023 14:09:45 +0800 Subject: [PATCH 226/235] + project: add functions to batch check date. --- module/project/js/batchedit.ui.js | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/module/project/js/batchedit.ui.js b/module/project/js/batchedit.ui.js index bfd8106aac..23ab14488e 100644 --- a/module/project/js/batchedit.ui.js +++ b/module/project/js/batchedit.ui.js @@ -1,3 +1,5 @@ +let batchIgnoreTips = []; + /** * 更新可用工作日天数。 * Update work days. @@ -15,6 +17,66 @@ function batchComputeWorkDays() $tr.find('[name^=days]').val(computeDaysDelta(beginDate, endDate)); } +/** + * 检查项目起止日期是否超出父项目集起止日期。 + * Check whether the start and end dates of the project exceed the start and end dates of the parent program. + * + * @access public + * @return void + */ +function batchCheckDate() +{ + const $tr = $(this).closest('tr'); + const index = $tr.data('index'); + if(batchIgnoreTips[index]) return; + + const end = $tr.find('[name^=end]').val(); + const begin = $tr.find('[name^=begin]').val(); + if(!begin || !end) return; + + const selectedProgramID = $tr.find('[name^=parent]').val(); + if(selectedProgramID == 0 || selectedProgramID == undefined) + { + $tr.next('tr.dateTip').remove(); + return; + } + + const projectID = $tr.find('[name^=id]').val(); + $.get($.createLink('project', 'ajaxGetProjectFormInfo', 'objectType=project&objectID=' + projectID + '&selectedProgramID=' + selectedProgramID), function(response) + { + const data = JSON.parse(response); + const parentEnd = new Date(data.selectedProgramEnd); + const parentBegin = new Date(data.selectedProgramBegin); + const projectEnd = new Date(end); + const projectBegin = new Date(begin); + + if(projectBegin >= parentBegin && projectEnd <= parentEnd) + { + $tr.next('tr.dateTip').remove(); + return; + } + + if($tr.next('tr.dateTip').length == 0) $tr.after($('#dateTipTemplate tr').clone()); + $tr.next('tr.dateTip').find('.beginLess').toggleClass('hidden', projectBegin >= parentBegin).find('.parentBegin').text(data.selectedProgramBegin); + $tr.next('tr.dateTip').find('.endGreater').toggleClass('hidden', projectEnd <= parentEnd).find('.parentEnd').text(data.selectedProgramEnd); + $tr.next('tr.dateTip').find('a').attr('onclick', 'batchIgnoreTip(' + index + ')'); + }); +} + +/** + * 忽略日期提示。 + * Ignore date tips. + * + * @access public + * @param int index + * @return void + */ +batchIgnoreTip = function(index) +{ + $('tr[data-index="' + index + '"]').next('tr.dateTip').remove(); + batchIgnoreTips[index] = true; +} + window.renderRowData = function($row, index, row) { /* 如果某个项目是长期项目,更新计划完成日期和可用工作日的样式。*/ From a3d28687366b8cec90e057a0b5f866f9a689b33e Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 20 Nov 2023 14:11:44 +0800 Subject: [PATCH 227/235] * project: refactor the function to check date. --- module/project/js/common.ui.js | 108 ++++++++++++--------------------- 1 file changed, 39 insertions(+), 69 deletions(-) diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js index 1bcb0b692c..c79ba5831c 100644 --- a/module/project/js/common.ui.js +++ b/module/project/js/common.ui.js @@ -1,11 +1,9 @@ const DAY_MILLISECONDS = 24 * 60 * 60 * 1000; -window.ignoreTips = { - 'beyondBudgetTip' : false, - 'dateTip' : false -}; - -var batchEditDateTips = new Array(); +const ignoreTips = { + budgetTip: false, + dateTip: false +} /** * 处理项目类型改变的交互。 @@ -103,8 +101,6 @@ function computeWorkDays() $('#delta' + days).prop('checked', true); } } - - outOfDateTip(); } /** @@ -258,84 +254,58 @@ function budgetOverrunTips() } /** - *The date is out of the range of the parent project set, and a prompt is given. + * The date is out of the range of the parent project set, and a prompt is given. * - * @param string $currentID * @access public * @return void */ -function outOfDateTip(currentID) +function checkDate() { - if(window.ignoreTips['dateTip']) return; - if(typeof(systemMode) != 'undefined' && systemMode == 'light') return; - if(batchEditDateTips.includes(Number(currentID))) return; + if(ignoreTips['dateTip']) return; - var end = currentID ? $('#ends\\[' + currentID + '\\]').val() : $('#end').val(); - var begin = currentID ? $('#begins\\[' + currentID + '\\]').val() : $('#begin').val(); - if($('#dateTip.text-remind').length > 0) $('#dateTip').closest('.form-row').remove(); - if(currentID) $('#dateTip\\[' + currentID + '\\]').remove(); + const begin = $('#begin').zui('datePicker').$.value; + const end = $('#end').zui('datePicker').$.value; + if(!begin || !end) return; - if(end == longTime) end = LONG_TIME; - if(end.length > 0 && begin.length > 0) + const selectedProgramID = $('[name=parent]').val(); + if(selectedProgramID == 0 || selectedProgramID == undefined) { - var selectedProgramID = currentID ? $("[name='parents\[" + currentID + "\]']").val() : $('#parent').val(); - - if(selectedProgramID == 0 || selectedProgramID == undefined) return; - - if(typeof(projectID) == 'undefined') projectID = 0; - projectID = currentID ? $('#projectIdList\\['+ currentID + '\\]').val() : projectID; - $.get($.createLink('project', 'ajaxGetProjectFormInfo', 'objectType=project&objectID=' + projectID + '&selectedProgramID=' + selectedProgramID), function(data) - { - var data = JSON.parse(data); - var parentEnd = new Date(data.selectedProgramEnd); - var parentBegin = new Date(data.selectedProgramBegin); - var projectEnd = new Date(end); - var projectBegin = new Date(begin); - - var beginLessThanParentTip = beginLessThanParent + data.selectedProgramBegin; - var endGreatThanParentTip = endGreatThanParent + data.selectedProgramEnd; - - if(projectBegin >= parentBegin && projectEnd <= parentEnd) return; - - var dateTip = ""; - if(projectBegin < parentBegin) - { - dateTip = currentID ? beginLessThanParentTip + "'>

" + beginLessThanParentTip : beginLessThanParentTip; - } - else if(projectEnd > parentEnd) - { - dateTip = currentID ? endGreatThanParentTip + "'>

" + endGreatThanParentTip : endGreatThanParentTip; - } - - if(currentID) - { - $("#projects\\[" + currentID + "\\]").after("" + ignore + "

"); - $('#dateTip'+ currentID).parent().css('line-height', '0') - } - else - { - $('#begin').closest('.form-row').after("

" + dateTip + "

" + ignore + "

"); - } - }); + $('#dateTip, #beginLess, #endGreater').addClass('hidden'); + return; } + + if(typeof(projectID) == 'undefined') projectID = 0; + $.get($.createLink('project', 'ajaxGetProjectFormInfo', 'objectType=project&objectID=' + projectID + '&selectedProgramID=' + selectedProgramID), function(response) + { + const data = JSON.parse(response); + const parentEnd = new Date(data.selectedProgramEnd); + const parentBegin = new Date(data.selectedProgramBegin); + const projectEnd = new Date(end); + const projectBegin = new Date(begin); + + if(projectBegin >= parentBegin && projectEnd <= parentEnd) + { + $('#dateTip, #beginLess, #endGreater').addClass('hidden'); + return; + } + + $('#dateTip').removeClass('hidden').find('#beginLess').toggleClass('hidden', projectBegin >= parentBegin).find('.parentBegin').text(data.selectedProgramBegin); + $('#dateTip').removeClass('hidden').find('#endGreater').toggleClass('hidden', projectEnd <= parentEnd).find('.parentEnd').text(data.selectedProgramEnd); + }); } /** - * Make this prompt no longer appear. + * 忽略提示信息。 + * Ignore tips. * - * @param string $obj - * @param string $currentID + * @param string $tip * @access public * @return void */ -window.ignoreTip = function(obj, currentID) +function ignoreTip(tip) { - var parentID = obj.parentNode.id; - currentID ? $('#dateTip' + currentID).parent().parent().remove() : $('#' + parentID).closest('.form-row').remove(); - - if(parentID == 'dateTip') window.ignoreTips['dateTip'] = true; - if(parentID == 'dateTip' + currentID) batchEditDateTips.push(currentID); - if(parentID == 'beyondBudgetTip') window.ignoreTips['beyondBudgetTip'] = true; + $('#' + tip).remove(); + ignoreTips[tip] = true; } /** From e874b8d4f06ea22eafcb11e833c3dc5b5cf5ea44 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 14:27:19 +0800 Subject: [PATCH 228/235] * Fixed the warn when story has stages. --- module/story/ui/edit.html.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/story/ui/edit.html.php b/module/story/ui/edit.html.php index 4b8c4dfc53..3cbeb955ac 100644 --- a/module/story/ui/edit.html.php +++ b/module/story/ui/edit.html.php @@ -21,12 +21,12 @@ $multiplePlan = ($product->type != 'normal' && empty($story->branch) && $planCou $minStage = $story->stage; $stageList = implode(',', array_keys($this->lang->story->stageList)); $minStagePos = strpos($stageList, $minStage); -if(!empty($story->stages) and $branchTagOption) +if(!empty($story->stages) && isset($fields['stage']['options'])) { foreach($story->stages as $branch => $stage) { $position = strpos(",{$stageList},", ",{$stage},"); - if($position !== false and $position > $minStagePos) + if($position !== false && $position > $minStagePos) { $minStage = $stage; $minStagePos = $position; From a94207923a187fbd2ab2dd50acc5124ef0f9bbff Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 06:27:57 +0000 Subject: [PATCH 229/235] * Format codes. --- module/product/ui/batchedit.html.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/module/product/ui/batchedit.html.php b/module/product/ui/batchedit.html.php index ec47a0d69e..fbe4b32f95 100644 --- a/module/product/ui/batchedit.html.php +++ b/module/product/ui/batchedit.html.php @@ -38,10 +38,7 @@ $fieldNameList = array_keys($items); $productData = array(); foreach($products as $product) { - foreach($fieldNameList as $fieldName) - { - $productData[$product->id][$fieldName] = zget($product, $fieldName, $fieldName == 'productIdList' ? $product->id : ''); - } + foreach($fieldNameList as $fieldName) $productData[$product->id][$fieldName] = zget($product, $fieldName, $fieldName == 'productIdList' ? $product->id : ''); } formBatchPanel From 711633cb706eafac33564e019c13fdff064903a7 Mon Sep 17 00:00:00 2001 From: daitingting Date: Mon, 20 Nov 2023 06:28:19 +0000 Subject: [PATCH 230/235] * Add pager on feature bar. * Adjust PM field. --- module/product/js/project.ui.js | 1 - module/product/ui/project.html.php | 13 ++++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/module/product/js/project.ui.js b/module/product/js/project.ui.js index bfaabf406e..90af80a236 100644 --- a/module/product/js/project.ui.js +++ b/module/product/js/project.ui.js @@ -51,6 +51,5 @@ window.renderCustomCell = function(result, {col, row}) if(col.name == 'end') result = [row.data.end]; if(col.name == 'status') result = [row.data.statusTitle]; - if(col.name == 'PM') result = ["" + row.data.PM + ""]; return result; } diff --git a/module/product/ui/project.html.php b/module/product/ui/project.html.php index 56aa659d51..3c650759cd 100644 --- a/module/product/ui/project.html.php +++ b/module/product/ui/project.html.php @@ -18,7 +18,7 @@ dropmenu(set::text($product->name)); featureBar ( set::current($status), - set::linkParams("status={key}&productID={$product->id}&branch={$branchID}"), + set::linkParams("status={key}&productID={$product->id}&branch={$branchID}&involved={$involved}&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"), checkbox ( set::id('involved'), @@ -39,7 +39,7 @@ if($branchStatus != 'closed') { toolbar ( - !common::hasPriv('project', 'manageProducts') ? null : item(set(array + !hasPriv('project', 'manageProducts') ? null : item(set(array ( 'icon' => 'link', 'text' => $lang->product->link2Project, @@ -47,7 +47,7 @@ if($branchStatus != 'closed') 'url' => '#link2Project', 'data-toggle' => 'modal' ))), - !common::hasPriv('project', 'create') ? null : item(set(array + !hasPriv('project', 'create') ? null : item(set(array ( 'icon' => 'plus', 'text' => $lang->project->create, @@ -97,8 +97,11 @@ foreach($config->productProject->showFields as $showField) $cols[$showField]['group'] = 0; } $cols['id']['checkbox'] = false; -$cols['PM']['link'] = helper::createLink('user', 'profile', 'userID={PMUserID}', '', true); -$cols['PM']['type'] = 'html'; + +$cols['PM']['type'] = 'link'; +$cols['PM']['link'] = helper::createLink('user', 'profile', 'userID={PMUserID}', '', true); +$cols['PM']['data-toggle'] = 'modal'; + if(!in_array($this->config->systemMode, array('ALM', 'PLM'))) unset($cols['program']); if(!str_contains('all,undone', $status)) unset($cols['status']); From 1baf8eab92dd34fd8bf1188aeb2ea88e32cd7b89 Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 14:48:04 +0800 Subject: [PATCH 231/235] * Fixed the error when edit a story. --- module/story/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/story/model.php b/module/story/model.php index ee156d33d7..fe645b668f 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -751,7 +751,7 @@ class storyModel extends model /* Set new stage and update story sort of plan when story plan has changed. */ if($oldStory->plan != $story->plan) { - $this->updateStoryOrderOfPlan($storyID, $story->plan, $oldStory->plan); // Insert a new story sort in this plan. + $this->updateStoryOrderOfPlan($storyID, (string)$story->plan, $oldStory->plan); // Insert a new story sort in this plan. if(empty($oldStory->plan) or empty($story->plan)) $this->setStage($storyID); // Set new stage for this story. if(!empty($oldStory->plan)) $this->action->create('productplan', (int)$oldStory->plan, 'unlinkstory', '', $storyID); if(!empty($story->plan)) $this->action->create('productplan', (int)$story->plan, 'linkstory', '', $storyID); From b028082c248cf0dfbe70a68a0b4a55b9077a315a Mon Sep 17 00:00:00 2001 From: wangxuepeng Date: Mon, 20 Nov 2023 14:54:07 +0800 Subject: [PATCH 232/235] * Change to new writing method. --- module/story/ui/batchtotask.html.php | 2 +- module/story/ui/change.html.php | 10 +++++----- module/story/ui/review.html.php | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/module/story/ui/batchtotask.html.php b/module/story/ui/batchtotask.html.php index a0c2ce49ff..1445635b7a 100644 --- a/module/story/ui/batchtotask.html.php +++ b/module/story/ui/batchtotask.html.php @@ -53,7 +53,7 @@ foreach($stories as $storyID => $story) formBatchPanel ( - set::id('dataform'), + setID('dataform'), set::title($lang->story->batchToTask), set::items($fields), set::maxRows(count($data)), diff --git a/module/story/ui/change.html.php b/module/story/ui/change.html.php index 399d0d89c1..1f99385162 100644 --- a/module/story/ui/change.html.php +++ b/module/story/ui/change.html.php @@ -55,7 +55,7 @@ $formItems['reviewer'] = formGroup setClass('input-group-addon'), checkbox ( - set::id('needNotReview'), + setID('needNotReview'), set::name('needNotReview'), set::checked($needReview), set::text($lang->story->needNotReview), @@ -96,7 +96,7 @@ $formItems['title'] = formGroup setClass('input-group-addon'), checkbox ( - set::id('relievedTwins'), + setID('relievedTwins'), set::name('relievedTwins'), set::value(1), $lang->story->relievedTwinsRelation @@ -174,8 +174,8 @@ if($this->config->vision != 'or') $formItems['affected'] = $getAffectedTabs($sto $formActions = formRow ( setClass('form-actions form-group no-label'), - btn(setClass('primary'), set::id('saveButton'), $lang->save), - btn(setClass('secondary'), set::id('saveDraftButton'), $lang->story->doNotSubmit), + btn(setClass('primary'), setID('saveButton'), $lang->save), + btn(setClass('secondary'), setID('saveDraftButton'), $lang->story->doNotSubmit), backBtn($lang->goback) ); @@ -183,7 +183,7 @@ formPanel ( on::click('#saveButton', 'customSubmit'), on::click('#saveDraftButton', 'customSubmit'), - set::id('dataform'), + setID('dataform'), set::actions(false), $formTitle, $formItems, diff --git a/module/story/ui/review.html.php b/module/story/ui/review.html.php index 632d2926a7..3a7928a943 100644 --- a/module/story/ui/review.html.php +++ b/module/story/ui/review.html.php @@ -42,12 +42,12 @@ foreach($fields as $field => $attr) if($this->config->vision != 'or') $formItems['affected'] = $getAffectedTabs($story, $users); $formItems['result']->add(on::change('switchShow(e.target);')); -$formItems['assignedTo']->add(set::id('assignedToBox'))->add(set::hidden(!$isLastOne)); -$formItems['closedReason']->add(set::id('rejectedReasonBox'))->add(set::hidden(true))->add(on::change('setStory(e.target);')); -$formItems['duplicateStory']->add(set::id('duplicateStoryBox'))->add(set::hidden(true)); -$formItems['pri']->add(set::id('priBox'))->add(set::hidden(true)); -$formItems['estimate']->add(set::id('estimateBox'))->add(set::hidden(true)); -$formItems['childStories']->add(set::id('childStoriesBox'))->add(set::hidden(true)); +$formItems['assignedTo']->add(setID('assignedToBox'))->add(set::hidden(!$isLastOne)); +$formItems['closedReason']->add(setID('rejectedReasonBox'))->add(set::hidden(true))->add(on::change('setStory(e.target);')); +$formItems['duplicateStory']->add(setID('duplicateStoryBox'))->add(set::hidden(true)); +$formItems['pri']->add(setID('priBox'))->add(set::hidden(true)); +$formItems['estimate']->add(setID('estimateBox'))->add(set::hidden(true)); +$formItems['childStories']->add(setID('childStoriesBox'))->add(set::hidden(true)); $formItems['status']->add(set::hidden(true)); modalHeader(); @@ -55,7 +55,7 @@ panel ( setClass('panel-form mx-auto'), form($formItems), - h::hr(set::className('mt-6 mb-6')), + h::hr(setClass('mt-6 mb-6')), history() ); From 928a483d06ec60c09e5c8841ca82662d2c04e4e7 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 14:54:11 +0800 Subject: [PATCH 233/235] * Fix bug, ignore branch name for normal product in project::view. --- module/project/control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/project/control.php b/module/project/control.php index ccfb83fc22..794f616a09 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -591,7 +591,7 @@ class project extends control $this->view->statData = $this->project->getStatData($projectID); $this->view->workhour = $this->project->getWorkhour($projectID); $this->view->planGroup = $this->loadModel('execution')->getPlans(array_keys($products)); - $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), '', $linkedBranches); + $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'ignoreNormal', $linkedBranches); $this->view->dynamics = $this->loadModel('action')->getDynamic('all', 'all', 'date_desc', 50, 'all', $projectID); $this->view->programList = $this->loadModel('program')->getPairsByList(explode(',', trim($project->path, ','))); $this->view->users = $userPairs; From c3be21c4a7915cf6a7666fd1581967313c2eeae9 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 20 Nov 2023 14:55:54 +0800 Subject: [PATCH 234/235] * Fix bug, ignore branch name for normal product in execution::view. --- module/execution/zen.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/zen.php b/module/execution/zen.php index f724d59c64..3a84f96b71 100644 --- a/module/execution/zen.php +++ b/module/execution/zen.php @@ -498,7 +498,7 @@ class executionZen extends execution $this->view->users = $userPairs; $this->view->userList = $userList; $this->view->products = $products; - $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), '', $linkedBranches); + $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'ignoreNormal', $linkedBranches); $this->view->planGroups = $this->execution->getPlans(array_keys($products)); $this->view->actions = $this->loadModel('action')->getList('execution', $executionID); $this->view->dynamics = $this->loadModel('action')->getDynamic('all', 'all', 'date_desc', 50, 'all', 'all', $executionID); From 7ebbc44f16e13299b0e654d77ae8032db5af4db1 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 20 Nov 2023 15:02:54 +0800 Subject: [PATCH 235/235] * Adjust for account view page in modal. --- module/account/ui/view.html.php | 6 +++++- module/todo/ui/view.html.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/module/account/ui/view.html.php b/module/account/ui/view.html.php index f0ef685a63..fe77b8af19 100644 --- a/module/account/ui/view.html.php +++ b/module/account/ui/view.html.php @@ -11,7 +11,11 @@ declare(strict_types=1); namespace zin; global $lang; -if(isAjaxRequest('modal')) unset($config->account->actionList['edit']['data-toggle']); +if(isAjaxRequest('modal')) +{ + $config->account->actionList['edit']['data-load'] = 'modal'; + unset($config->account->actionList['edit']['data-toggle']); +} $actions = $this->loadModel('common')->buildOperateMenu($account); detailHeader diff --git a/module/todo/ui/view.html.php b/module/todo/ui/view.html.php index bfeb5d9387..be5a333a47 100644 --- a/module/todo/ui/view.html.php +++ b/module/todo/ui/view.html.php @@ -243,7 +243,7 @@ $fnGenerateFloatToolbarBtns = function() use ($lang, $config, $todo, $projects, $canStart && $status == 'wait' ? $actionList['main'][] = array('icon' => 'play', 'url' => createLink('todo', 'start', "todoID={$todo->id}"), 'text' => $lang->todo->abbr->start) : null; $canActivate && ($status == 'done' || $status == 'closed') ? $actionList['main'][] = array('icon' => 'magic', 'url' => createLink('todo', 'activate', "todoID={$todo->id}"), 'text' => $lang->activate) : null; $canClose && $status == 'done' ? $actionList['main'][] = array('icon' => 'off', 'url' => createLink('todo', 'close', "todoID={$todo->id}"), 'text' => $lang->close) : null; - $canEdit ? $actionList['main'][] = array('icon' => 'edit', 'url' => createLink('todo', 'edit', "todoID={$todo->id}"), 'text' => $lang->edit) : null; + $canEdit ? $actionList['main'][] = array('icon' => 'edit', 'url' => createLink('todo', 'edit', "todoID={$todo->id}"), 'data-load' => $isInModal ? 'modal' : null, 'text' => $lang->edit) : null; $canDelete ? $actionList['main'][] = array('icon' => 'trash', 'url' => createLink('todo', 'delete', "todoID={$todo->id}"), 'text' => $lang->delete) : null; /* The status is 'done' or 'closed' without more action buttons. */