From 9f2e4e99ea4353fe0094e4b40a223e41dfaa59ba Mon Sep 17 00:00:00 2001 From: Catouse Date: Thu, 21 Apr 2016 15:12:54 +0800 Subject: [PATCH] * fix product tasks tree view. --- module/project/css/tree.css | 9 ++- module/project/lang/en.php | 2 +- module/project/lang/zh-cn.php | 2 +- module/project/model.php | 99 ++++++++++++++++++++----------- module/project/view/tree.html.php | 16 +++-- 5 files changed, 84 insertions(+), 44 deletions(-) diff --git a/module/project/css/tree.css b/module/project/css/tree.css index 69efbce00f..ffa0a9a4f5 100644 --- a/module/project/css/tree.css +++ b/module/project/css/tree.css @@ -5,9 +5,10 @@ #projectTree li > .tree-item-wrapper > .tree-toggle {display: block} #projectTree li > .tree-item-wrapper:hover {display: block; background-color: #edf3fe; cursor: pointer; margin-left: -20px; padding-left: 20px;} #projectTree li {line-height: 30px; padding-top: 0; padding-bottom: 0} -#projectTree .item-type-product > .tree-item-wrapper {display: block; background-color: #edf3fe; margin-left: -20px; padding-left: 20px; border-bottom: 1px solid #ddd; cursor: pointer} -#projectTree .item-type-product > .tree-item-wrapper:hover {background-color: #eee} -#projectTree .item-type-product.open > .tree-item-wrapper {border-bottom: none} +#projectTree > li > .tree-item-wrapper {display: block; background-color: #edf3fe; margin-left: -20px; padding-left: 20px; border-bottom: 1px solid #ddd; cursor: pointer} +#projectTree > li > .tree-item-wrapper:hover {background-color: #eee} +#projectTree > li.open > .tree-item-wrapper {border-bottom: none} +#projectTree > li.open + li > .tree-item-wrapper {border-top: 1px solid #ddd} #projectTree.tree li>.list-toggle:before {content: '\e6bb'} #projectTree.tree li.open>.list-toggle:before {content: '\e6b8';} #projectTree.tree li>.list-toggle {top: 2px} @@ -18,3 +19,5 @@ .tree-view-btn {min-width: 36px;} .main > .panel > .panel-heading > .panel-actions {margin-top: -8px; margin-right: -12px;} + +.label-task-count {background: #ddd; color: #333} diff --git a/module/project/lang/en.php b/module/project/lang/en.php index 1ba9e345ec..4a07f4eb11 100644 --- a/module/project/lang/en.php +++ b/module/project/lang/en.php @@ -108,6 +108,7 @@ $lang->project->team = 'Team'; $lang->project->doc = 'Doc'; $lang->project->manageProducts = 'Link ' . $lang->productCommon; $lang->project->linkStory = 'Link story'; +$lang->project->unlinkStoryTasks = 'Tasks of unlink story'; $lang->project->view = "Info"; $lang->project->create = "Add"; $lang->project->copy = "Copy a {$lang->projectCommon}"; @@ -256,4 +257,3 @@ $lang->project->treeLevel['product'] = array('icon' => 'icon-cube', 'text' => 'P $lang->project->treeLevel['module'] = array('icon' => 'icon-bookmark-empty', 'text' => 'Modules view'); $lang->project->treeLevel['story'] = array('icon' => 'icon-lightbulb', 'text' => 'Stories view'); $lang->project->treeLevel['task'] = array('icon' => 'icon-tasks', 'text' => 'Tasks view'); -$lang->project->treeLevel['custom'] = array('icon' => 'icon-align-left', 'text' => 'Custom view'); diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php index 92753d9edc..8a324538eb 100644 --- a/module/project/lang/zh-cn.php +++ b/module/project/lang/zh-cn.php @@ -108,6 +108,7 @@ $lang->project->team = '团队成员'; $lang->project->doc = '文档列表'; $lang->project->manageProducts = '关联' . $lang->productCommon; $lang->project->linkStory = '关联需求'; +$lang->project->unlinkStoryTasks = '未关联需求任务'; $lang->project->view = "{$lang->projectCommon}概况"; $lang->project->create = "添加{$lang->projectCommon}"; $lang->project->copy = "复制{$lang->projectCommon}"; @@ -260,4 +261,3 @@ $lang->project->treeLevel['product'] = array('icon' => 'icon-cube', 'text' => ' $lang->project->treeLevel['module'] = array('icon' => 'icon-bookmark-empty', 'text' => '模块视图'); $lang->project->treeLevel['story'] = array('icon' => 'icon-lightbulb', 'text' => '需求视图'); $lang->project->treeLevel['task'] = array('icon' => 'icon-tasks', 'text' => '任务视图'); -$lang->project->treeLevel['custom'] = array('icon' => 'icon-align-left', 'text' => '自定义'); diff --git a/module/project/model.php b/module/project/model.php index 889b3f1aa4..2bc7f863e9 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -1944,6 +1944,54 @@ class projectModel extends model return $chartData; } + /** + * Format task list for tree view + * @param array $tasks + * @access public + * @return array + */ + public function formatTasksForTree($tasks) + { + static $users; + if(empty($users)) $users = $this->loadModel('user')->getPairs('noletter'); + + $taskItems = array(); + foreach ($tasks as $task) + { + $taskItem = new stdclass(); + $taskItem->type = 'task'; + $taskItem->id = $task->id; + $taskItem->title = $task->name; + $taskItem->color = $task->color; + $taskItem->pri = (int) $task->pri; + $taskItem->status = $task->status; + $taskItem->estimate = $task->estimate; + $taskItem->consumed = $task->consumed; + $taskItem->left = $task->left; + $taskItem->assignedTo = $users[$task->assignedTo]; + $taskItem->url = helper::createLink('task', 'view', "task=$task->id"); + $taskItem->storyChanged = $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion; + + $buttons = ''; + $buttons .= common::buildIconButton('task', 'assignTo', "projectID=$task->project&taskID=$task->id", $task, 'list', '', '', 'iframe', true); + $buttons .= common::buildIconButton('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); + + $buttons .= common::buildIconButton('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true); + if($browseType == 'needconfirm') + { + $lang->task->confirmStoryChange = $lang->confirm; + $buttons .= common::buildIconButton('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin'); + } + $buttons .= common::buildIconButton('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); + $buttons .= common::buildIconButton('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); + $buttons .= common::buildIconButton('task', 'edit', "taskID=$task->id", '', 'list'); + + $taskItem->buttons = $buttons; + $taskItems[] = $taskItem; + } + return $taskItems; + } + /** * Build product task tree item * @param object $tree @@ -1991,41 +2039,8 @@ class projectModel extends model $storyTasks = $this->task->getStoryTasks($story->id, $projectID); if(!empty($storyTasks)) { - $taskItems = array(); - foreach ($storyTasks as $task) - { - $taskItem = new stdclass(); - $taskItem->type = 'task'; - $taskItem->id = $task->id; - $taskItem->title = $task->name; - $taskItem->color = $task->color; - $taskItem->pri = $task->pri; - $taskItem->status = $task->status; - $taskItem->estimate = $task->estimate; - $taskItem->consumed = $task->consumed; - $taskItem->left = $task->left; - $taskItem->assignedTo = $users[$task->assignedTo]; - $taskItem->url = helper::createLink('task', 'view', "task=$task->id"); - $taskItem->storyChanged = $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion; - - $buttons = ''; - $buttons .= common::buildIconButton('task', 'assignTo', "projectID=$task->project&taskID=$task->id", $task, 'list', '', '', 'iframe', true); - $buttons .= common::buildIconButton('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - - $buttons .= common::buildIconButton('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true); - if($browseType == 'needconfirm') - { - $lang->task->confirmStoryChange = $lang->confirm; - $buttons .= common::buildIconButton('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin'); - } - $buttons .= common::buildIconButton('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - $buttons .= common::buildIconButton('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true); - $buttons .= common::buildIconButton('task', 'edit', "taskID=$task->id", '', 'list'); - - $taskItem->buttons = $buttons; - $taskItems[] = $taskItem; - } - + $taskItems = $this->formatTasksForTree($storyTasks); + $storyItem->tasksCount = count($taskItems); $storyItem->children = array(); $storyItem->children[] = array('id' => 'tasks' . $story->id, 'tasks' => $taskItems, 'type' => 'tasks', 'actions' => false); } @@ -2056,6 +2071,20 @@ class projectModel extends model $tree[] = $this->buildProductTaskTree($productItem, $projectID); } + $zeroStoryTasks = $this->loadModel('task')->getStoryTasks(0, $projectID); + if(count($zeroStoryTasks)) + { + $zeroStoryTasks = $this->formatTasksForTree($zeroStoryTasks); + $unlinkStoryItem = new stdclass(); + $unlinkStoryItem->type = 'unlinkStory'; + $unlinkStoryItem->id = 'unlinkStory'; + $unlinkStoryItem->tasksCount = count($zeroStoryTasks); + $unlinkStoryItem->title = $this->lang->project->unlinkStoryTasks; + $unlinkStoryItem->children = array(); + $unlinkStoryItem->actions = false; + $unlinkStoryItem->children[] = array('id' => 'tasks0', 'tasks' => $zeroStoryTasks, 'type' => 'tasks', 'actions' => false); + $tree[] = $unlinkStoryItem; + } return $tree; } } diff --git a/module/project/view/tree.html.php b/module/project/view/tree.html.php index b4b38d3cb0..43eac6cceb 100644 --- a/module/project/view/tree.html.php +++ b/module/project/view/tree.html.php @@ -46,7 +46,6 @@ $(function() var hoursFormat = 'project->hours ?>'; var viewLevel = '' || 'custom'; var data = $.parseJSON(''); - console.log('data', data); var $tree = $('#projectTree'); var statusMap = $.parseJSON('task->statusList);?>'); var selectCustomLevel = function() {$('.tree-view-btn.active').removeClass('active').filter('[data-type="custom"]').addClass('active');}; @@ -82,7 +81,11 @@ $(function() } else if(item.type === 'story') { - $li.append(' ').append($('').attr({href: item.url}).text('#' + item.storyId + ' ' + item.title).css('color', item.color)); + $li.append(' ').append($('').attr({href: item.url}).text('#' + item.storyId + ' ' + item.title).css('color', item.color)); + if(item.children && item.children.length) + { + if(item.tasksCount) $li.append(' ' + item.tasksCount + ''); + } } else if(item.type === 'task') { @@ -97,10 +100,10 @@ $(function() $.each(item.tasks, function(idx, task) { var $tr = $(''); - $tr.append($('').append('' + task.pri + '')); + $tr.append($('').append('' + (task.pri || '') + '')); $tr.append($('').addClass('text-left').append($('').attr({href: task.url}).text('#' + task.id + ' ' + task.title).css('color', task.color))); - $tr.append($('').addClass(task.storyChanged ? 'warning' : task.status).text(statusMap[task.status])); $tr.append($('').html(task.assignedTo ? (' ' + task.assignedTo) : '')); + $tr.append($('').addClass(task.storyChanged ? 'warning' : task.status).text(statusMap[task.status])); $tr.append($('').text(hoursFormat.replace('%s', task.estimate).replace('%s', task.consumed).replace('%s', task.left))); $tr.append($('').html(task.buttons)); $tbody.append($tr); @@ -108,6 +111,11 @@ $(function() $li.append($table); } } + else if(item.type === 'unlinkStory') + { + $li.append($(' ' + item.title + '')).addClass('tree-toggle'); + if(item.tasksCount) $li.append(' ' + item.tasksCount + ''); + } else { $li.addClass('tree-toggle').append($(' ' + (item.title || item.name) + ''));