From a755136ee9050de5674246093559cf74b5aa7bca Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Fri, 29 Oct 2021 14:11:03 +0800 Subject: [PATCH 1/8] * limit range for iframe modal triggers. --- module/execution/js/kanban.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index cbd3d5e7a3..21ba8814c4 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -595,7 +595,7 @@ $(function() if(browseType == 'all' || browseType == 'task') createKanban('task', kanbanGroup.task, commonOptions); /* Init iframe modals */ - $(document).on('click', '.iframe', function(event) + $(document).on('click', '#kanbans .iframe,.contextmenu-menu .iframe', function(event) { $(this).modalTrigger({show: true, width: '500px'}); event.preventDefault(); From b9c0807023a64a997fc67088be8e5ab55d8accfd Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 29 Oct 2021 17:20:20 +0800 Subject: [PATCH 2/8] * merge code of kanban lang. --- module/kanban/lang/zh-cn.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/kanban/lang/zh-cn.php b/module/kanban/lang/zh-cn.php index 97831f5dc5..ae6a129662 100644 --- a/module/kanban/lang/zh-cn.php +++ b/module/kanban/lang/zh-cn.php @@ -44,7 +44,7 @@ $lang->kanban->noLimit = '不限制∞'; $lang->kanban->setLane = '泳道设置'; $lang->kanban->laneName = '泳道名称'; $lang->kanban->laneColor = '泳道颜色'; -$lang->kanban->setLaneColumn = '看板列设置'; +$lang->kanban->setColumn = '看板列设置'; $lang->kanban->columnName = '看板列名称'; $lang->kanban->columnColor = '看板列颜色'; $lang->kanban->noColumnUniqueName = '看板列名称已存在'; From 970763b0c5ecef28e42fa214e94b11e2d491dde3 Mon Sep 17 00:00:00 2001 From: liyuchun Date: Mon, 1 Nov 2021 11:32:21 +0800 Subject: [PATCH 3/8] * Adjust create object in kanban. --- module/bug/control.php | 3 +++ module/execution/control.php | 18 +++++++++++++----- module/execution/js/kanban.js | 24 ++++++++++++------------ module/execution/view/kanban.html.php | 14 +++++++------- module/task/control.php | 4 ++-- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/module/bug/control.php b/module/bug/control.php index 9a34399db4..e53565f090 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -649,6 +649,9 @@ class bug extends control } setcookie('bugModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false); + + /* If link from no head then reload. */ + if(isonlybody()) die(js::reload('parent.parent')); die(js::locate($this->createLink('bug', 'browse', "productID={$productID}&branch=$branch&browseType=unclosed¶m=0&orderBy=id_desc"), 'parent')); } diff --git a/module/execution/control.php b/module/execution/control.php index 054bb6656f..195b1621b4 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1838,6 +1838,11 @@ class execution extends control $this->app->session->set('taskList', $uri, 'execution'); $this->app->session->set('bugList', $uri, 'qa'); + /* Load language. */ + $this->app->loadLang('story'); + $this->app->loadLang('task'); + $this->app->loadLang('bug'); + /* Compatibility IE8. */ if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); @@ -2404,6 +2409,8 @@ class execution extends control { $this->execution->linkStory($objectID); if($object->type != 'project' and $object->project != 0) $this->execution->linkStory($object->project); + + if(isonlybody()) die(js::reload('parent')); die(js::locate($browseLink)); } @@ -3120,13 +3127,14 @@ class execution extends control /** * Import stories by plan. * - * @param int $executionID - * @param int $planID - * @param int $productID + * @param int $executionID + * @param int $planID + * @param int $productID + * @param string $fromMethod * @access public * @return void */ - public function importPlanStories($executionID, $planID, $productID = 0) + public function importPlanStories($executionID, $planID, $productID = 0, $fromMethod = 'story') { $planStories = $planProducts = array(); $planStory = $this->loadModel('story')->getPlanStories($planID); @@ -3161,7 +3169,7 @@ class execution extends control $param = "projectID=$executionID"; } if($count != 0) echo js::alert(sprintf($this->lang->execution->haveDraft, $count)) . js::locate($this->createLink($moduleName, 'story', $param)); - die(js::locate(helper::createLink($moduleName, 'story', $param), 'parent')); + die(js::locate(helper::createLink($moduleName, $fromMethod, $param))); } /** diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 6a08704864..b04ff9f886 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -491,8 +491,8 @@ function createColumnMenu(options) var kanbanID = options.kanban; var items = []; - if(priv.hasEditName) items.push({label: executionLang.editName, url: $.createLink('kanban', 'setColumn', 'col=' + col.columnID + '&executionID=' + executionID), className: 'iframe'}) - if(priv.hasSetWIP) items.push({label: executionLang.setWIP, url: $.createLink('kanban', 'setWIP', 'col=' + col.columnID + '&executionID=' + executionID), className: 'iframe'}) + if(priv.hasEditName) items.push({label: executionLang.editName, url: $.createLink('kanban', 'setColumn', 'col=' + col.columnID + '&executionID=' + executionID), className: 'iframe', attrs: {'data-width': '500px'}}) + if(priv.hasSetWIP) items.push({label: executionLang.setWIP, url: $.createLink('kanban', 'setWIP', 'col=' + col.columnID + '&executionID=' + executionID), className: 'iframe', attrs: {'data-width': '500px'}}) items.push({label: executionLang.sortColumn, items: ['按ID倒序', '按ID顺序'], className: 'iframe', onClick: handleSortColCards}) return items; } @@ -509,20 +509,20 @@ function createColumnCreateMenu(options) if(col.laneType == 'story') { - if(priv.canCreateStory) items.push({label: storyLang.create, url: $.createLink('story', 'create', 'productID=' + productID)}); - if(priv.canBatchCreateStory) items.push({label: storyLang.batchCreate, url: $.createLink('story', 'batchcreate', 'productID=' + productID)}); - if(priv.canLinkStory) items.push({label: executionLang.linkStory, url: $.createLink('execution', 'linkStory', 'executionID=' + executionID)}); + if(priv.canCreateStory) items.push({label: storyLang.create, url: $.createLink('story', 'create', 'productID=' + productID, '', true), className: 'iframe'}); + if(priv.canBatchCreateStory) items.push({label: storyLang.batchCreate, url: $.createLink('story', 'batchcreate', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&executionID=' + executionID, '', true), className: 'iframe'}); + if(priv.canLinkStory) items.push({label: executionLang.linkStory, url: $.createLink('execution', 'linkStory', 'executionID=' + executionID, '', true), className: 'iframe', attrs: {'data-width': '85%'}}); if(priv.canLinkStoryByPlane) items.push({label: executionLang.linkStoryByPlan, url: '#linkStoryByPlan', 'attrs' : {'data-toggle': 'modal'}}); } else if(col.laneType == 'bug') { - if(priv.canCreateBug) items.push({label: bugLang.create, url: $.createLink('bug', 'create', 'productID=0&moduleID=0&extra=executionID=' + executionID)}); - if(priv.canBatchCreateBug) items.push({label: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&moduleID=0&executionID=' + executionID)}); + if(priv.canCreateBug) items.push({label: bugLang.create, url: $.createLink('bug', 'create', 'productID=0&moduleID=0&extra=executionID=' + executionID, '', true), className: 'iframe'}); + if(priv.canBatchCreateBug) items.push({label: bugLang.batchCreate, url: $.createLink('bug', 'batchcreate', 'productID=' + productID + '&moduleID=0&executionID=' + executionID, '', true), className: 'iframe'}); } else { - if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID)}); - if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID)}); + if(priv.canCreateTask) items.push({label: taskLang.create, url: $.createLink('task', 'create', 'executionID=' + executionID, '', true), className: 'iframe'}); + if(priv.canBatchCreateTask) items.push({label: taskLang.batchCreate, url: $.createLink('task', 'batchcreate', 'executionID=' + executionID, '', true), className: 'iframe'}); } return items; } @@ -673,9 +673,9 @@ $(function() if(browseType == 'all' || browseType == 'task') createKanban('task', kanbanGroup.task, commonOptions); /* Init iframe modals */ - $(document).on('click', '.iframe', function(event) + $(document).on('click', '#kanbans .iframe,.contextmenu-menu .iframe', function(event) { - $(this).modalTrigger({show: true, width: '500px'}); + $(this).modalTrigger({show: true}); event.preventDefault(); }); @@ -706,7 +706,7 @@ $(function() var planID = $('#plan').val(); if(planID) { - parent.location.href = createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID); + location.href = createLink('execution', 'importPlanStories', 'executionID=' + executionID + '&planID=' + planID + '&productID=0&fromMethod=kanban'); } }) }); diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index 39f516e3aa..9dc2a8709c 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -68,16 +68,16 @@ diff --git a/module/task/control.php b/module/task/control.php index 06a407a729..a6890a14d0 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -302,8 +302,8 @@ class task extends control /* Return task id list when call the API. */ if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'idList' => $taskIDList)); - /* Locate the browser. */ - if(!empty($iframe)) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent')); + /* If link from no head then reload. */ + if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent')); return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $taskLink)); } From c08c981ab0d1041a55422ca1c5d537b91d3f5800 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Mon, 1 Nov 2021 13:13:56 +0800 Subject: [PATCH 4/8] * Display the sub Lane view kanban. --- db/update15.7.sql | 1 + db/zentao.sql | 1 + module/execution/control.php | 4 +-- module/execution/js/kanban.js | 20 +++++++++---- module/execution/view/kanban.html.php | 1 + module/kanban/model.php | 42 ++++++++++++++++----------- 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/db/update15.7.sql b/db/update15.7.sql index 6f0f50c608..a45191525f 100644 --- a/db/update15.7.sql +++ b/db/update15.7.sql @@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS `zt_kanbanlane` ( `id` int(8) NOT NULL AUTO_INCREMENT, `execution` mediumint(8) NOT NULL DEFAULT '0', `type` char(30) NOT NULL, + `groupby` char(30) NOT NULL, `extra` char(30) NOT NULL, `name` varchar(255) NOT NULL DEFAULT '', `color` char(30) NOT NULL, diff --git a/db/zentao.sql b/db/zentao.sql index 91efb3fcce..60f013c5d7 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -600,6 +600,7 @@ CREATE TABLE IF NOT EXISTS `zt_kanbanlane` ( `id` int(8) NOT NULL AUTO_INCREMENT, `execution` mediumint(8) NOT NULL DEFAULT '0', `type` char(30) NOT NULL, + `groupby` char(30) NOT NULL, `extra` char(30) NOT NULL, `name` varchar(255) NOT NULL DEFAULT '', `color` char(30) NOT NULL, diff --git a/module/execution/control.php b/module/execution/control.php index 054bb6656f..0583f7e0d9 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1841,11 +1841,11 @@ class execution extends control /* Compatibility IE8. */ if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); - $kanbanGroup = $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType); + $kanbanGroup = $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy); if(empty($kanbanGroup)) { $this->kanban->createLanes($executionID, $browseType, $groupBy); - $kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType); + $kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy); } $this->execution->setMenu($executionID); diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 6a08704864..1320523f63 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -663,14 +663,22 @@ $(function() /* Hide group menu. */ hideGroupMenu(); - /* Create story kanban 创建需求看板 */ - if(browseType == 'all' || browseType == 'story') createKanban('story', kanbanGroup.story, commonOptions); + if(groupBy == 'default') + { + /* Create story kanban 创建需求看板 */ + if(browseType == 'all' || browseType == 'story') createKanban('story', kanbanGroup.story, commonOptions); - /* Create bug kanban 创建 Bug 看板 */ - if(browseType == 'all' || browseType == 'bug') createKanban('bug', kanbanGroup.bug, commonOptions); + /* Create bug kanban 创建 Bug 看板 */ + if(browseType == 'all' || browseType == 'bug') createKanban('bug', kanbanGroup.bug, commonOptions); - /* Create task kanban 创建 任务 看板 */ - if(browseType == 'all' || browseType == 'task') createKanban('task', kanbanGroup.task, commonOptions); + /* Create task kanban 创建 任务 看板 */ + if(browseType == 'all' || browseType == 'task') createKanban('task', kanbanGroup.task, commonOptions); + } + else + { + /* Create kanban by group. 分泳道创建看板. */ + createKanban(browseType, kanbanGroup[groupBy], commonOptions); + } /* Init iframe modals */ $(document).on('click', '.iframe', function(event) diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index 39f516e3aa..c3158959c8 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -116,6 +116,7 @@ + dao->select('*')->from(TABLE_KANBANLANE) ->where('execution')->eq($executionID) ->andWhere('deleted')->eq(0) - ->beginIF($browseType != 'all')->andWhere('type')->eq($browseType) - ->beginIF($groupBy != 'default')->andWhere('extra')->eq($groupBy) + ->beginIF($browseType != 'all')->andWhere('type')->eq($browseType)->fi() + ->beginIF($groupBy == 'default')->andWhere('groupby')->eq('')->fi() + ->beginIF($groupBy != 'default')->andWhere('groupby')->eq($groupBy)->fi() ->fetchAll('id'); if(empty($lanes)) return array(); @@ -63,13 +64,13 @@ class kanbanModel extends model { $laneData = array(); $columnData = array(); - $laneType = $lane->type; + $laneType = $groupBy == 'default' ? $lane->type : $lane->groupby; - $laneData['id'] = $laneType; + $laneData['id'] = $groupBy == 'default' ? $lane->type : $lane->groupby . '-' . $lane->extra; $laneData['name'] = $lane->name; $laneData['color'] = $lane->color; $laneData['order'] = $lane->order; - $laneData['defaultCardType'] = $laneType; + $laneData['defaultCardType'] = $lane->type; foreach($columns[$laneID] as $columnID => $column) { @@ -79,7 +80,7 @@ class kanbanModel extends model $columnData[$column->id]['name'] = $column->name; $columnData[$column->id]['color'] = $column->color; $columnData[$column->id]['limit'] = $column->limit; - $columnData[$column->id]['laneType'] = $laneType; + $columnData[$column->id]['laneType'] = $lane->type; $columnData[$column->id]['asParent'] = $column->parent == -1 ? true : false; if($column->parent > 0) @@ -92,18 +93,18 @@ class kanbanModel extends model foreach($cardIdList as $cardID) { $cardData = array(); - $objects = zget($objectGroup, $laneType, array()); + $objects = zget($objectGroup, $lane->type, array()); $object = zget($objects, $cardID, array()); $cardData['id'] = $object->id; $cardData['order'] = $cardOrder; $cardData['pri'] = $object->pri ? $object->pri : ''; - $cardData['estimate'] = $laneType == 'bug' ? '' : $object->estimate; + $cardData['estimate'] = $lane->type == 'bug' ? '' : $object->estimate; $cardData['assignedTo'] = $object->assignedTo; - $cardData['deadline'] = $laneType == 'task' ? $object->deadline : ''; - $cardData['severity'] = $laneType == 'bug' ? $object->severity : ''; + $cardData['deadline'] = $lane->type == 'task' ? $object->deadline : ''; + $cardData['severity'] = $lane->type == 'bug' ? $object->severity : ''; - if($laneType == 'task') + if($lane->type == 'task') { $cardData['name'] = $object->name; } @@ -112,9 +113,9 @@ class kanbanModel extends model $cardData['title'] = $object->title; } - if($laneType == 'story') $cardData['menus'] = $storyCardMenu[$object->id]; - if($laneType == 'bug') $cardData['menus'] = $bugCardMenu[$object->id]; - if($laneType == 'task') $cardData['menus'] = $taskCardMenu[$object->id]; + if($lane->type == 'story') $cardData['menus'] = $storyCardMenu[$object->id]; + if($lane->type == 'bug') $cardData['menus'] = $bugCardMenu[$object->id]; + if($lane->type == 'task') $cardData['menus'] = $taskCardMenu[$object->id]; $laneData['cards'][$column->type][] = $cardData; $cardOrder ++; @@ -125,7 +126,7 @@ class kanbanModel extends model $kanbanGroup[$laneType]['id'] = $laneType; $kanbanGroup[$laneType]['columns'] = array_values($columnData); $kanbanGroup[$laneType]['lanes'][] = $laneData; - $kanbanGroup[$laneType]['defaultCardType'] = $laneType; + $kanbanGroup[$laneType]['defaultCardType'] = $lane->type; } return $kanbanGroup; @@ -209,7 +210,8 @@ class kanbanModel extends model $lane = new stdClass(); $lane->execution = $executionID; $lane->type = $type; - $lane->extra = $groupBy; + $lane->groupby = $groupBy; + $lane->extra = $groupKey; $lane->name = $laneName; $lane->color = '#7ec5ff'; $lane->order = $laneOrder; @@ -368,6 +370,8 @@ class kanbanModel extends model $stories = $this->loadModel('story')->getExecutionStories($executionID); foreach($stories as $storyID => $story) { + if($lane->groupby and $story->{$lane->groupby} != $lane->extra) continue; + foreach($this->config->kanban->storyColumnStageList as $colType => $stage) { if(strpos(',ready,develop,test,', $colType) !== false) continue; @@ -391,6 +395,8 @@ class kanbanModel extends model $bugs = $this->loadModel('bug')->getExecutionBugs($executionID); foreach($bugs as $bugID => $bug) { + if($lane->groupby and $bug->{$lane->groupby} != $lane->extra) continue; + foreach($this->config->kanban->bugColumnStatusList as $colType => $status) { if(strpos(',resolving,fixing,test,testing,tested,', $colType) !== false) continue; @@ -422,6 +428,8 @@ class kanbanModel extends model $tasks = $this->loadModel('execution')->getKanbanTasks($executionID); foreach($tasks as $taskID => $task) { + if($lane->groupby and $task->{$lane->groupby} != $lane->extra) continue; + foreach($this->config->kanban->taskColumnStatusList as $colType => $status) { if($colType == 'develop') continue; From c28e4c1b61d730596f58302e1d852ef65d922697 Mon Sep 17 00:00:00 2001 From: dingna Date: Mon, 1 Nov 2021 09:22:01 +0800 Subject: [PATCH 5/8] * Fix code for task#43401,#43403,#43404,#43405,#43398,#43399. --- module/execution/css/kanban.css | 3 ++- module/execution/js/kanban.js | 21 +-------------------- module/execution/view/kanban.html.php | 3 ++- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/module/execution/css/kanban.css b/module/execution/css/kanban.css index a04ce818c5..cef2290d04 100644 --- a/module/execution/css/kanban.css +++ b/module/execution/css/kanban.css @@ -31,4 +31,5 @@ .dropdown-menu a {text-align: left;} .scrollbar-hover {max-height: 2000px; overflow: scroll !important;} -.c-type, .c-group {width: 150px !important; overflow: unset; display: "";} +.c-type, .c-group {width: 150px !important; overflow: unset;} +.c-type {margin-left: 0px !important;} diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 1320523f63..52180a5e36 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -660,9 +660,6 @@ $(function() onRenderCount: renderColumnCount }; - /* Hide group menu. */ - hideGroupMenu(); - if(groupBy == 'default') { /* Create story kanban 创建需求看板 */ @@ -719,26 +716,10 @@ $(function() }) }); -/** - * Hide group menu. - * - * @access public - * @return void - */ -function hideGroupMenu() -{ - var type = $('#type').val(); - if(type == 'all') $('.c-group').hide(); -} - $('#type').change(function() { var type = $('#type').val(); - if(type == 'all') - { - $('.c-group').hide(); - } - else + if(type != 'all') { $('.c-group').show(); $.get(createLink('execution', 'ajaxGetGroup', 'type=' + type), function(data) diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index c3158959c8..7c82a688b9 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -13,12 +13,13 @@