Add a dashboard (first version)

This commit is contained in:
Frédéric Guillot 2014-10-14 22:02:35 -04:00
parent d0e6d2e1f1
commit 286b193566
23 changed files with 218 additions and 44 deletions

View File

@ -13,17 +13,21 @@ use Model\Project as ProjectModel;
class App extends Base
{
/**
* Redirect to the project creation page or the board controller
* Dashboard for the current user
*
* @access public
*/
public function index()
{
if ($this->project->countByStatus(ProjectModel::ACTIVE)) {
$this->response->redirect('?controller=board');
}
else {
$this->redirectNoProject();
}
$user_id = $this->acl->getUserId();
$projects = $this->projectPermission->getAllowedProjects($user_id);
$this->response->html($this->template->layout('app_index', array(
'board_selector' => $projects,
'events' => $this->projectActivity->getProjects(array_keys($projects), 10),
'tasks' => $this->taskFinder->getAllTasksByUser($user_id),
'menu' => 'dashboard',
'title' => t('Dashboard'),
)));
}
}

View File

@ -379,7 +379,7 @@ class Project extends Base
$project = $this->getProject();
$this->response->html($this->template->layout('project_activity', array(
'events' => $this->projectActivity->getAll($project['id']),
'events' => $this->projectActivity->getProject($project['id']),
'menu' => 'projects',
'project' => $project,
'title' => t('%s\'s activity', $project['name'])
@ -427,6 +427,7 @@ class Project extends Base
'project_id' => $project['id'],
),
'project' => $project,
'menu' => 'projects',
'columns' => $this->board->getColumnsList($project['id']),
'categories' => $this->category->getList($project['id'], false),
'title' => $project['name'].($nb_tasks > 0 ? ' ('.$nb_tasks.')' : '')
@ -461,6 +462,7 @@ class Project extends Base
'limit' => $limit,
),
'project' => $project,
'menu' => 'projects',
'columns' => $this->board->getColumnsList($project['id']),
'categories' => $this->category->getList($project['id'], false),
'tasks' => $tasks,

View File

@ -59,7 +59,7 @@ class User extends Base
$this->response->redirect('?'.$redirect_query);
}
else {
$this->response->redirect('?controller=board');
$this->response->redirect('?controller=app');
}
}

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
'Started on %B %e, %Y' => 'Commençé le %d/%m/%Y',
'Start date' => 'Date de début',
'Time estimated' => 'Temps estimé',
'There is nothing assigned to you.' => 'Aucune tâche assignée pour vous.',
'My tasks' => 'Mes tâches',
'Activity stream' => 'Flux d\'activité',
'Dashboard' => 'Tableau de bord',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -543,4 +543,8 @@ return array(
// 'Started on %B %e, %Y' => '',
// 'Start date' => '',
// 'Time estimated' => '',
// 'There is nothing assigned to you.' => '',
// 'My tasks' => '',
// 'Activity stream' => '',
// 'Dashboard' => '',
);

View File

@ -61,15 +61,32 @@ class ProjectActivity extends Base
* @param integer $limit Maximum events number
* @return array
*/
public function getAll($project_id, $limit = 50)
public function getProject($project_id, $limit = 50)
{
return $this->getProjects(array($project_id), $limit);
}
/**
* Get all events for the given projects list
*
* @access public
* @param integer $project_id Project id
* @param integer $limit Maximum events number
* @return array
*/
public function getProjects(array $projects, $limit = 50)
{
if (empty($projects)) {
return array();
}
$events = $this->db->table(self::TABLE)
->columns(
self::TABLE.'.*',
User::TABLE.'.username AS author_username',
User::TABLE.'.name AS author_name'
)
->eq('project_id', $project_id)
->in('project_id', $projects)
->join(User::TABLE, 'id', 'creator_id')
->desc('id')
->limit($limit)

View File

@ -111,6 +111,33 @@ class TaskFinder extends Base
->findAll();
}
/**
* Get all open tasks for a given user
*
* @access public
* @param integer $user_id User id
* @return array
*/
public function getAllTasksByUser($user_id)
{
return $this->db
->table(Task::TABLE)
->columns(
'tasks.id',
'tasks.title',
'tasks.date_due',
'tasks.date_creation',
'tasks.project_id',
'tasks.color_id',
'projects.name AS project_name'
)
->join(Project::TABLE, 'id', 'project_id')
->eq('tasks.owner_id', $user_id)
->eq('tasks.is_active', Task::STATUS_OPEN)
->asc('tasks.id')
->findAll();
}
/**
* Get all tasks for a given project and status
*

View File

@ -0,0 +1,45 @@
<section id="main">
<div class="page-header">
<h2><?= t('Dashboard') ?></h2>
</div>
<section id="dashboard">
<div class="dashboard-left-column">
<h2><?= t('My tasks') ?></h2>
<?php if (empty($tasks)): ?>
<p class="alert"><?= t('There is nothing assigned to you.') ?></p>
<?php else: ?>
<table>
<tr>
<th>&nbsp;</th>
<th width="15%"><?= t('Project') ?></th>
<th width="40%"><?= t('Title') ?></th>
<th><?= t('Due date') ?></th>
<th><?= t('Date created') ?></th>
</tr>
<?php foreach ($tasks as $task): ?>
<tr>
<td class="task-table task-<?= $task['color_id'] ?>">
<?= Helper\a('#'.$task['id'], 'task', 'show', array('task_id' => $task['id'])) ?>
</td>
<td>
<?= Helper\a(Helper\escape($task['project_name']), 'board', 'show', array('project_id' => $task['project_id'])) ?>
</td>
<td>
<?= Helper\a(Helper\escape($task['title']), 'task', 'show', array('task_id' => $task['id'])) ?>
</td>
<td>
<?= dt('%B %e, %Y', $task['date_due']) ?>
</td>
<td>
<?= dt('%B %e, %Y', $task['date_creation']) ?>
</td>
</tr>
<?php endforeach ?>
</table>
<?php endif ?>
</div>
<div class="dashboard-right-column">
<h2><?= t('Activity stream') ?></h2>
<?= Helper\template('project_events', array('events' => $events)) ?>
</section>
</section>

View File

@ -50,6 +50,9 @@
</select>
</li>
<?php endif ?>
<li <?= isset($menu) && $menu === 'dashboard' ? 'class="active"' : '' ?>>
<a href="?controller=app"><?= t('Dashboard') ?></a>
</li>
<li <?= isset($menu) && $menu === 'boards' ? 'class="active"' : '' ?>>
<a href="?controller=board"><?= t('Boards') ?></a>
</li>

View File

@ -9,29 +9,10 @@
</ul>
</div>
<section>
<?php if (empty($events)): ?>
<p class="alert"><?= t('No activity.') ?></p>
<?php else: ?>
<?php if ($project['is_public']): ?>
<p class="pull-right"><i class="fa fa-rss-square"></i> <?= Helper\a(t('RSS feed'), 'project', 'feed', array('token' => $project['token'])) ?></p>
<?php endif ?>
<?php foreach ($events as $event): ?>
<div class="activity-event">
<p class="activity-datetime">
<?php if (Helper\contains($event['event_name'], 'task')): ?>
<i class="fa fa-newspaper-o"></i>
<?php elseif (Helper\contains($event['event_name'], 'subtask')): ?>
<i class="fa fa-tasks"></i>
<?php elseif (Helper\contains($event['event_name'], 'comment')): ?>
<i class="fa fa-comments-o"></i>
<?php endif ?>
&nbsp;<?= dt('%B %e, %Y at %k:%M %p', $event['date_creation']) ?>
</p>
<div class="activity-content"><?= $event['event_content'] ?></div>
</div>
<?php endforeach ?>
<?php endif ?>
<?= Helper\template('project_events', array('events' => $events)) ?>
</section>
</section>

View File

@ -0,0 +1,21 @@
<?php if (empty($events)): ?>
<p class="alert"><?= t('No activity.') ?></p>
<?php else: ?>
<?php foreach ($events as $event): ?>
<div class="activity-event">
<p class="activity-datetime">
<?php if (Helper\contains($event['event_name'], 'subtask')): ?>
<i class="fa fa-tasks"></i>
<?php elseif (Helper\contains($event['event_name'], 'task')): ?>
<i class="fa fa-newspaper-o"></i>
<?php elseif (Helper\contains($event['event_name'], 'comment')): ?>
<i class="fa fa-comments-o"></i>
<?php endif ?>
&nbsp;<?= dt('%B %e, %Y at %k:%M %p', $event['date_creation']) ?>
</p>
<div class="activity-content"><?= $event['event_content'] ?></div>
</div>
<?php endforeach ?>
<?php endif ?>

View File

@ -13,7 +13,7 @@
<?php foreach ($tasks as $task): ?>
<tr>
<td class="task-table task-<?= $task['color_id'] ?>">
<a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>"><?= Helper\escape($task['id']) ?></a>
<a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>">#<?= Helper\escape($task['id']) ?></a>
</td>
<td>
<?= Helper\in_list($task['column_id'], $columns) ?>

View File

@ -1119,6 +1119,22 @@ tr td.task-orange,
color: #555;
}
/* dashboard */
#dashboard table {
font-size: 0.95em;
}
.dashboard-left-column {
width: 55%;
float: left;
}
.dashboard-right-column {
margin-left: 5%;
width: 40%;
float: left;
}
/* confirmation box */
.confirm {
max-width: 700px;

View File

@ -67,6 +67,15 @@ var Kanboard = (function() {
dateFormat: 'yy-mm-dd',
constrainInput: false
});
// Project select box
$("#board-selector").chosen({
width: 180
});
$("#board-selector").change(function() {
window.location = "?controller=board&action=show&project_id=" + $(this).val();
});
}
};
@ -229,17 +238,11 @@ Kanboard.Board = (function() {
return {
Init: function() {
Kanboard.Before();
board_load_events();
filter_load_events();
// Project select box
$("#board-selector").chosen({
width: 180
});
$("#board-selector").change(function() {
window.location = "?controller=board&action=show&project_id=" + $(this).val();
});
}
};
@ -274,6 +277,18 @@ Kanboard.Project = (function() {
})();
// Dashboard related functions
Kanboard.Dashboard = (function() {
return {
Init: function() {
Kanboard.Before();
}
};
})();
// Initialization
$(function() {
if ($("#board").length) {
@ -282,6 +297,9 @@ $(function() {
else if ($("#task-section").length) {
Kanboard.Task.Init();
}
else if ($("#dashboard").length) {
Kanboard.Dashboard.Init();
}
else if ($("#project-section").length) {
Kanboard.Project.Init();
}

View File

@ -24,7 +24,7 @@ class ProjectActivityTest extends Base
$this->assertTrue($e->createEvent(1, 2, 1, Task::EVENT_UPDATE, array('task' => $tf->getById(2))));
$this->assertFalse($e->createEvent(1, 1, 0, Task::EVENT_OPEN, array('task' => $tf->getbyId(1))));
$events = $e->getAll(1);
$events = $e->getProject(1);
$this->assertNotEmpty($events);
$this->assertTrue(is_array($events));
@ -50,7 +50,7 @@ class ProjectActivityTest extends Base
$this->assertTrue($e->createEvent(1, 1, 1, Task::EVENT_UPDATE, array('task' => $tf->getbyId(1))));
}
$events = $e->getAll(1);
$events = $e->getProject(1);
$this->assertNotEmpty($events);
$this->assertTrue(is_array($events));
@ -80,7 +80,7 @@ class ProjectActivityTest extends Base
$this->assertEquals($nb_events, $this->registry->shared('db')->table('project_activities')->count());
$e->cleanup($max);
$events = $e->getAll(1);
$events = $e->getProject(1);
$this->assertNotEmpty($events);
$this->assertTrue(is_array($events));