diff --git a/module/project/control.php b/module/project/control.php index 47eff3bad5..eee780130c 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -1247,7 +1247,7 @@ class project extends control * @access public * @return void */ - public function kanban($projectID, $orderBy = 'pri_asc') + public function kanban($projectID, $type = 'story', $orderBy = 'pri_asc') { /* Save to session. */ $uri = $this->app->getURI(true); @@ -1260,19 +1260,22 @@ class project extends control $this->project->setMenu($this->projects, $projectID); $project = $this->loadModel('project')->getById($projectID); - $stories = $this->loadModel('story')->getProjectStories($projectID, $orderBy); $tasks = $this->project->getKanbanTasks($projectID, "id"); $bugs = $this->loadModel('bug')->getProjectBugs($projectID); - $stories = $this->project->getKanbanGroupData($stories, $tasks, $bugs); + $stories = $this->loadModel('story')->getProjectStories($projectID, $orderBy); - $this->view->title = $this->lang->project->kanban; - $this->view->position[] = html::a($this->createLink('project', 'browse', "projectID=$projectID"), $project->name); - $this->view->position[] = $this->lang->project->kanban; - $this->view->stories = $stories; - $this->view->realnames = $this->loadModel('user')->getPairs('noletter'); - $this->view->orderBy = $orderBy; - $this->view->projectID = $projectID; - $this->view->project = $project; + $kanbanGroup = $this->project->getKanbanGroupData($stories, $tasks, $bugs, $type); + + $this->view->title = $this->lang->project->kanban; + $this->view->position[] = html::a($this->createLink('project', 'browse', "projectID=$projectID"), $project->name); + $this->view->position[] = $this->lang->project->kanban; + $this->view->stories = $stories; + $this->view->realnames = $this->loadModel('user')->getPairs('noletter'); + $this->view->orderBy = $orderBy; + $this->view->projectID = $projectID; + $this->view->project = $project; + $this->view->type = $type; + $this->view->kanbanGroup = $kanbanGroup; $kanbanSetting = $this->project->getKanbanSetting($projectID); diff --git a/module/project/css/kanban.css b/module/project/css/kanban.css index cae429cd04..1d9ebc48cf 100644 --- a/module/project/css/kanban.css +++ b/module/project/css/kanban.css @@ -63,12 +63,12 @@ table th.col-closed {width:14%} .board {background: #333; color: #f1f1f1; outline: 1px solid rgba(0,0,0,.1); outline-offset: -1px;} .board:hover {outline: 1px solid rgba(0,0,0,.3); color:#fff} -.board-bug-cancel, .board-task-cancel {background: #333; opacity: 0.7;} -.board-bug-wait, .board-task-wait {background: #2b529c;opacity: 0.7;} -.board-task-pause {background: #E48600;opacity: 0.7;} -.board-bug-doing, .board-task-doing {background: #D2322D;opacity: 0.7;} -.board-bug-done, .board-task-done {background: #229F24;opacity: 0.7;} -.board-bug-closed, .board-task-closed {background: #777; opacity: 0.7;} +.board-bug-cancel, .board-task-cancel {background: #333; opacity: 1;} +.board-bug-wait, .board-task-wait {background: #2b529c;opacity: 1;} +.board-task-pause {background: #E48600;opacity: 1;} +.board-bug-doing, .board-task-doing {background: #D2322D;opacity: 1;} +.board-bug-done, .board-task-done {background: #229F24;opacity: 1;} +.board-bug-closed, .board-task-closed {background: #777; opacity: 1;} .board-bug-cancel.inverse, .board-task-cancel.inverse {opacity: 1;} .board-bug-wait.inverse, .board-task-wait.inverse {opacity: 1} diff --git a/module/project/model.php b/module/project/model.php index a5ff1bcb47..11232375de 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -2058,41 +2058,49 @@ class projectModel extends model * @access public * @return array */ - public function getKanbanGroupData($stories, $tasks, $bugs) + public function getKanbanGroupData($stories, $tasks, $bugs, $type = 'story') { - $stories['nostory'] = new stdclass(); + $kanbanGroup = array(); + if($type == 'story') $kanbanGroup = $stories; + foreach($tasks as $task) { - $storyID = $task->storyID; - $status = $task->status; - if(!empty($storyID) and isset($stories[$storyID])) + $groupKey = $type == 'story' ? $task->storyID : $task->$type; + + $status = $task->status; + if(!empty($groupKey) and (($type == 'story' and isset($stories[$groupKey])) or $type != 'story')) { - $stories[$storyID]->tasks[$status][] = $task; + if(!isset($kanbanGroup[$groupKey])) $kanbanGroup[$groupKey] = new stdclass(); + $kanbanGroup[$groupKey]->tasks[$status][] = $task; } else { - $noStoryTasks[$status][] = $task; + $noKeyTasks[$status][] = $task; } } - if(isset($noStoryTasks)) $stories['nostory']->tasks = $noStoryTasks; foreach($bugs as $bug) { - $storyID = $bug->story; + $groupKey = $type == 'finishedBy' ? $bug->resolvedBy : $bug->$type; + $status = $bug->status; $status = $status == 'active' ? 'wait' : ($status == 'resolved' ? ($bug->resolution == 'postponed' ? 'cancel' : 'done') : $status); - if(!empty($storyID) and isset($stories[$storyID])) + if(!empty($groupKey) and (($type == 'story' and isset($stories[$groupKey])) or $type != 'story')) { - $stories[$storyID]->bugs[$status][] = $bug; + if(!isset($kanbanGroup[$groupKey])) $kanbanGroup[$groupKey] = new stdclass(); + $kanbanGroup[$groupKey]->bugs[$status][] = $bug; } else { - $noStoryBugs[$status][] = $bug; + $noKeyBugs[$status][] = $bug; } } - if(isset($noStoryBugs)) $stories['nostory']->bugs = $noStoryBugs; - return $stories; + $kanbanGroup['nokey'] = new stdclass(); + if(isset($noKeyTasks)) $kanbanGroup['nokey']->tasks = $noKeyTasks; + if(isset($noKeyBugs)) $kanbanGroup['nokey']->bugs = $noKeyBugs; + + return $kanbanGroup; } /** diff --git a/module/project/view/kanban.html.php b/module/project/view/kanban.html.php index a8e56ac739..457de5ea64 100644 --- a/module/project/view/kanban.html.php +++ b/module/project/view/kanban.html.php @@ -24,17 +24,21 @@ $account = $this->app->user->account - = 2;?> - + 0) or $type != 'story');?> + @@ -48,6 +52,15 @@ $account = $this->app->user->account @@ -61,7 +74,7 @@ $account = $this->app->user->account
+ + + task->$type;?> +
- + @@ -69,12 +82,14 @@ $account = $this->app->user->account - - + $group):?> + - +
- id)):?> + + +
assignedTo == $account) echo ' inverse';?>' data-id='id?>'>
createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', 'class="kanbanFrame" title="' . $story->title . '"');?> @@ -103,13 +118,20 @@ $account = $this->app->user->account
estimate . 'h ';?>
+ +
+
+ +
+
+
- tasks[$col])):?> - tasks[$col] as $task):?> + tasks[$col])):?> + tasks[$col] as $task):?>
assignedTo == $account) echo ' inverse';?>' data-id='id?>' id='task-id?>'>
app->user->account $labelClass = $task->status == 'doing' ? 'label-delay-doing' : 'label-delay-wait'; echo "{$lang->task->delayed}"; } - echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), $task->name, '', 'class="kanbanFrame" title="' . $task->name . '"'); + $childrenAB = empty($task->parent) ? '' : "" . $lang->task->childrenAB . ' '; + echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), $childrenAB . $task->name, '', 'class="kanbanFrame" title="' . $task->name . '"'); ?>
@@ -126,7 +149,7 @@ $account = $this->app->user->account -
"; + $title = ''; + if($id == 'name') $title = " title='{$task->name}'"; + if($id == 'story') $title = " title='{$task->storyTitle}'"; + + echo ""; switch($id) { case 'id':