* fix product tasks tree view.
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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' => '自定义');
|
||||
|
||||
+64
-35
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ $(function()
|
||||
var hoursFormat = '<?php echo $lang->project->hours ?>';
|
||||
var viewLevel = '<?php echo $level ?>' || 'custom';
|
||||
var data = $.parseJSON('<?php echo json_encode($tree, JSON_HEX_QUOT | JSON_HEX_APOS);?>');
|
||||
console.log('data', data);
|
||||
var $tree = $('#projectTree');
|
||||
var statusMap = $.parseJSON('<?php echo json_encode($lang->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('<span><i class="icon icon-lightbulb text-muted"></i> </span>').append($('<a>').attr({href: item.url}).text('#' + item.storyId + ' ' + item.title).css('color', item.color));
|
||||
$li.append('<span class="tree-item-title"><i class="icon icon-lightbulb text-muted"></i> </span>').append($('<a>').attr({href: item.url}).text('#' + item.storyId + ' ' + item.title).css('color', item.color));
|
||||
if(item.children && item.children.length)
|
||||
{
|
||||
if(item.tasksCount) $li.append(' <span class="label label-task-count label-badge">' + item.tasksCount + '</span>');
|
||||
}
|
||||
}
|
||||
else if(item.type === 'task')
|
||||
{
|
||||
@@ -97,10 +100,10 @@ $(function()
|
||||
$.each(item.tasks, function(idx, task)
|
||||
{
|
||||
var $tr = $('<tr class="text-center"/>');
|
||||
$tr.append($('<td width="30"/>').append('<span class="pri' + task.pri + '">' + task.pri + '</span>'));
|
||||
$tr.append($('<td width="30"/>').append('<span class="pri' + task.pri + '">' + (task.pri || '') + '</span>'));
|
||||
$tr.append($('<td/>').addClass('text-left').append($('<a>').attr({href: task.url}).text('#' + task.id + ' ' + task.title).css('color', task.color)));
|
||||
$tr.append($('<td width="70"/>').addClass(task.storyChanged ? 'warning' : task.status).text(statusMap[task.status]));
|
||||
$tr.append($('<td width="90"/>').html(task.assignedTo ? ('<i class="icon icon-user text-muted"></i> ' + task.assignedTo) : ''));
|
||||
$tr.append($('<td width="70"/>').addClass(task.storyChanged ? 'warning' : task.status).text(statusMap[task.status]));
|
||||
$tr.append($('<td width="140"/>').text(hoursFormat.replace('%s', task.estimate).replace('%s', task.consumed).replace('%s', task.left)));
|
||||
$tr.append($('<td width="130"/>').html(task.buttons));
|
||||
$tbody.append($tr);
|
||||
@@ -108,6 +111,11 @@ $(function()
|
||||
$li.append($table);
|
||||
}
|
||||
}
|
||||
else if(item.type === 'unlinkStory')
|
||||
{
|
||||
$li.append($('<span class="tree-item-title"><i class="icon icon-tasks text-muted"></i> ' + item.title + '</span>')).addClass('tree-toggle');
|
||||
if(item.tasksCount) $li.append(' <span class="label label-task-count label-badge">' + item.tasksCount + '</span>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$li.addClass('tree-toggle').append($('<span class="tree-toggle"><i class="icon icon-bookmark-empty text-muted"></i> ' + (item.title || item.name) + '</span>'));
|
||||
|
||||
Reference in New Issue
Block a user