From 154c18ee430a2192bf3be6d68d8b37044a6f3a23 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Tue, 12 Jul 2022 11:07:16 +0800 Subject: [PATCH 1/2] * Finish task #60476. --- module/execution/control.php | 13 +++-- module/execution/css/kanban.css | 1 + module/execution/css/taskkanban.css | 1 + module/execution/js/kanban.js | 37 +++++++++++-- module/execution/js/taskkanban.js | 38 ++++++++++++-- module/execution/view/kanban.html.php | 5 ++ module/execution/view/taskkanban.html.php | 6 +++ module/kanban/lang/de.php | 3 ++ module/kanban/lang/en.php | 3 ++ module/kanban/lang/fr.php | 3 ++ module/kanban/lang/zh-cn.php | 3 ++ module/kanban/model.php | 64 ++++++++++++++++++----- 12 files changed, 154 insertions(+), 23 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index 9cf79b345f..42df62905e 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2469,11 +2469,12 @@ class execution extends control unset($this->lang->kanban->type['all']); } - $kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy); + if($groupBy == 'story' and $browseType == 'task' and !isset($this->lang->kanban->orderList[$orderBy])) $orderBy = 'pri_asc'; + $kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, '', $orderBy); if(empty($kanbanGroup)) { $this->kanban->createExecutionLane($executionID, $browseType, $groupBy); - $kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy); + $kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, '', $orderBy); } /* Determines whether an object is editable. */ @@ -4099,11 +4100,15 @@ class execution extends control * @param string $groupBy * @param string $from execution|RD * @param string $searchValue + * @param string $orderBy * @access public * @return array */ - public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution', $searchValue = '') + public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution', $searchValue = '', $orderBy = 'id_asc') { + $this->loadModel('kanban'); + if($groupBy == 'story' and $browseType == 'task' and !isset($this->lang->kanban->orderList[$orderBy])) $orderBy = 'pri_asc'; + $enterTime = date('Y-m-d H:i:s', $enterTime); $lastEditedTime = $this->dao->select("max(lastEditedTime) as lastEditedTime")->from(TABLE_KANBANLANE)->where('execution')->eq($executionID)->fetch('lastEditedTime'); @@ -4111,7 +4116,7 @@ class execution extends control if($from == 'RD') $this->session->set('rdSearchValue', $searchValue); if(strtotime($lastEditedTime) < 0 or $lastEditedTime > $enterTime or $groupBy != 'default' or !empty($searchValue)) { - $kanbanGroup = $from == 'execution' ? $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy, $searchValue) : $this->loadModel('kanban')->getRDKanban($executionID, $browseType, 'id_asc', 0, $groupBy, $searchValue); + $kanbanGroup = $from == 'execution' ? $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, $searchValue, $orderBy) : $this->kanban->getRDKanban($executionID, $browseType, $orderBy, 0, $groupBy, $searchValue); return print(json_encode($kanbanGroup)); } } diff --git a/module/execution/css/kanban.css b/module/execution/css/kanban.css index 936d99e76e..7a47cf694f 100644 --- a/module/execution/css/kanban.css +++ b/module/execution/css/kanban.css @@ -36,6 +36,7 @@ .region .kanban-header-col > .title {max-width: 80% !important;} .region .kanban-header-col > .title {margin: 0} .region .kanban-header-col > .title > span {display: inline-block; overflow: hidden; padding-right:2px; position: initial; max-width: 85px !important;} +.region .kanban-header-col > .title > span.storyColumn {max-width: 100% !important;} .region .kanban-header-col > .title > .text-grey {opacity: .5; font-weight: bold; color: #8b91a2;} .region .kanban-header-col > .title > .count {opacity: .5; font-weight: bold; color: #8b91a2;} .region .kanban-header-col > .title > .error {color: #333333; padding-left: 2px; font-size: 10px; padding-top: 1px; padding-right: 2px;} diff --git a/module/execution/css/taskkanban.css b/module/execution/css/taskkanban.css index 9cdad7095c..74960863c8 100644 --- a/module/execution/css/taskkanban.css +++ b/module/execution/css/taskkanban.css @@ -29,6 +29,7 @@ .kanban-affixed .kanban-header-col > .title > .text, .kanban-affixed .kanban-header-col > .title > .count {color: #fff!important;} .kanban-header-col > .title > .text {max-width: 110px !important;} +.kanban-header-col > .title > .storyColumn.text {max-width: 100% !important;} #kanbanContainer {margin: 0;} #kanbanContainer > .panel-body {overflow: auto;} diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 3c48a056e5..87678df4c9 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -547,6 +547,15 @@ function renderEstStarted(estStarted, status) */ function renderStoryItem(item, $item, col) { + if(groupBy == 'story' && item.id == '0') + { + $('.storyCell').css('width', '100%'); + $parentItem = $item[0] == undefined ? $('.storyCell') : $item.parent(); + $parentItem.addClass('text-center storyCell'); + $parentItem.css('line-height', ($parentItem.parent().height() - 20) + 'px'); + $item.replaceWith('' + item.title + ''); + return; + } var scaleSize = window.kanbanScaleSize; if(+$item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize); @@ -749,6 +758,14 @@ addColumnRenderer('task', renderTaskItem); */ function renderCount($count, count, column) { + if(groupBy == 'story' && column.type == 'story') + { + $count.prev().addClass('storyColumn'); + $count.prev().parent().append(''); + $count.remove(); + return; + } + /* Render WIP. */ var limit = !column.limit || column.limit == '-1' ? '' : column.limit; if($count.parent().find('.limit').length) @@ -793,6 +810,9 @@ function tips() */ function renderHeaderCol($column, column, $header, kanbanData) { + if(groupBy == 'story' && column.type == 'story') return; + console.log(groupBy); + console.log(column.type); /* Render group header. */ var privs = kanbanData.actions; var columnPrivs = kanbanData.columns[0].actions; @@ -850,6 +870,11 @@ function renderHeaderCol($column, column, $header, kanbanData) */ function renderLaneName($lane, lane, $kanban, columns, kanban) { + if(groupBy == 'story') + { + $lane.hide(); + return; + } if(groupBy != 'default') return; var canEditLaneColor = lane.actions.includes('editLaneColor'); var canEditLaneName = lane.actions.includes('editLaneName'); @@ -1375,7 +1400,7 @@ function handleSortCards(event) } else { - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD'), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD' + '&serachValue=' + rdSearchValue + '&orderBy=' + orderBy), function(data) { if(data && lastUpdateData !== data) { @@ -1567,6 +1592,12 @@ $(function() $('.color0 .cardcolor').css('border', '1px solid #fff'); }); + $(document).on('click', '#kanban span.caret.changeOrderBy', function(event) + { + orderBy = orderBy == 'pri_desc' ? 'pri_asc' : 'pri_desc'; + searchCards(rdSearchValue); + }) + /* Init sortable */ var sortType = ''; var $cards = null; @@ -1694,7 +1725,7 @@ $(function() { if(rdSearchValue == '') { - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue=' + rdSearchValue), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue=' + rdSearchValue + '&orderBy=' + orderBy), function(data) { if(lastUpdateData == '') lastUpdateData = data; if(data && lastUpdateData !== data) @@ -1800,7 +1831,7 @@ function toggleRDSearchBox() function searchCards(value) { rdSearchValue = value; - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue=' + rdSearchValue), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue=' + rdSearchValue + '&orderBy=' + orderBy), function(data) { lastUpdateData = data; kanbanData = $.parseJSON(data); diff --git a/module/execution/js/taskkanban.js b/module/execution/js/taskkanban.js index cb19dd35b8..0d963206ec 100644 --- a/module/execution/js/taskkanban.js +++ b/module/execution/js/taskkanban.js @@ -128,6 +128,15 @@ function renderEstStarted(estStarted, status) */ function renderStoryItem(item, $item, col) { + if(groupBy == 'story' && item.id == '0') + { + $('.storyCell').css('width', '100%'); + $parentItem = $item[0] == undefined ? $('.storyCell') : $item.parent(); + $parentItem.addClass('text-center storyCell'); + $parentItem.css('line-height', ($parentItem.parent().height() - 20) + 'px'); + $item.replaceWith('' + item.title + ''); + return; + } var scaleSize = window.kanbanScaleSize; if($item.attr('data-scale-size') !== scaleSize) $item.empty().attr('data-scale-size', scaleSize); @@ -330,6 +339,14 @@ addColumnRenderer('task', renderTaskItem); */ function renderColumnCount($count, count, col) { + if(groupBy == 'story' && col.type == 'story') + { + $count.prev().addClass('storyColumn'); + $count.prev().parent().append(''); + $count.remove(); + return; + } + var text = count + '/' + (col.limit < 0 ? '' : col.limit); $count.html(text + ''); @@ -370,7 +387,9 @@ function tips() function renderHeaderCol($col, col, $header, kanban) { if(col.asParent) $col = $col.children('.kanban-header-col'); - if($col.children('.actions').context != undefined) return; + if($col.children('.actions').context != undefined || (groupBy == 'story' && col.type == 'story')) return; + console.log(groupBy); + console.log(col.type); var $actions = $('
'); var printStoryButton = printTaskButton = printBugButton = false; @@ -410,6 +429,11 @@ function renderHeaderCol($col, col, $header, kanban) */ function renderLaneName($name, lane, $kanban, columns, kanban) { + if(groupBy == 'story') + { + $name.hide(); + return; + } if(lane.id != 'story' && lane.id != 'task' && lane.id != 'bug') return false; if(!$name.children('.actions').length && (priv.canSetLane || priv.canMoveLane)) { @@ -1167,7 +1191,7 @@ function handleSortCards(event) } else { - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=execution'), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=execution' + '&searchValue=' + searchValue + '&orderBy=' + orderBy), function(data) { if(data && lastUpdateData !== data) { @@ -1252,6 +1276,12 @@ $(function() event.preventDefault(); }); + $(document).on('click', '#kanbans span.caret.changeOrderBy', function(event) + { + orderBy = orderBy == 'pri_desc' ? 'pri_asc' : 'pri_desc'; + searchCards(searchValue); + }) + /* Init contextmenu */ $('#kanbans').on('click', '[data-contextmenu]', function(event) { @@ -1311,7 +1341,7 @@ $(function() lastUpdateData = ''; setInterval(function() { - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=execution&searchValue=' + searchValue), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=execution&searchValue=' + searchValue + '&orderBy' + orderBy), function(data) { if(lastUpdateData == '') lastUpdateData = data; if(data && lastUpdateData !== data) @@ -1447,7 +1477,7 @@ function toggleSearchBox() function searchCards(value) { searchValue = value; - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=execution&searchValue=' + value), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=execution&searchValue=' + value + '&orderBy=' + orderBy), function(data) { lastUpdateData = data; var kanbanData = $.parseJSON(data); diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index eaa09204f0..3b9e898d70 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -118,6 +118,11 @@ js::set('priv', ) ); ?> + + +