summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2014-10-14 22:02:35 -0400
committerFrédéric Guillot <fred@kanboard.net>2014-10-14 22:02:35 -0400
commit286b1935663ef3071ad6a0aae3078ad3a42b48e4 (patch)
tree80469612ac9feba9bea28c1ac7f263e680f52d49
parentd0e6d2e1f177cfe533ea7819bf79b0469b8d0cc2 (diff)
Add a dashboard (first version)
-rw-r--r--app/Controller/App.php18
-rw-r--r--app/Controller/Project.php4
-rw-r--r--app/Controller/User.php2
-rw-r--r--app/Locales/de_DE/translations.php4
-rw-r--r--app/Locales/es_ES/translations.php4
-rw-r--r--app/Locales/fi_FI/translations.php4
-rw-r--r--app/Locales/fr_FR/translations.php4
-rw-r--r--app/Locales/it_IT/translations.php4
-rw-r--r--app/Locales/pl_PL/translations.php4
-rw-r--r--app/Locales/pt_BR/translations.php4
-rw-r--r--app/Locales/ru_RU/translations.php4
-rw-r--r--app/Locales/sv_SE/translations.php4
-rw-r--r--app/Locales/zh_CN/translations.php4
-rw-r--r--app/Model/ProjectActivity.php21
-rw-r--r--app/Model/TaskFinder.php27
-rw-r--r--app/Templates/app_index.php45
-rw-r--r--app/Templates/layout.php3
-rw-r--r--app/Templates/project_activity.php21
-rw-r--r--app/Templates/project_events.php21
-rw-r--r--app/Templates/task_table.php2
-rw-r--r--assets/css/app.css16
-rw-r--r--assets/js/app.js36
-rw-r--r--tests/units/ProjectActivityTest.php6
23 files changed, 218 insertions, 44 deletions
diff --git a/app/Controller/App.php b/app/Controller/App.php
index b7f79b1d..feec4221 100644
--- a/app/Controller/App.php
+++ b/app/Controller/App.php
@@ -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'),
+ )));
}
}
diff --git a/app/Controller/Project.php b/app/Controller/Project.php
index 1fac3ffb..503eb3a5 100644
--- a/app/Controller/Project.php
+++ b/app/Controller/Project.php
@@ -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,
diff --git a/app/Controller/User.php b/app/Controller/User.php
index bbed9f6f..834b2379 100644
--- a/app/Controller/User.php
+++ b/app/Controller/User.php
@@ -59,7 +59,7 @@ class User extends Base
$this->response->redirect('?'.$redirect_query);
}
else {
- $this->response->redirect('?controller=board');
+ $this->response->redirect('?controller=app');
}
}
diff --git a/app/Locales/de_DE/translations.php b/app/Locales/de_DE/translations.php
index 4b901148..0fb5f38a 100644
--- a/app/Locales/de_DE/translations.php
+++ b/app/Locales/de_DE/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/es_ES/translations.php b/app/Locales/es_ES/translations.php
index 0cdd5f32..40a30bb4 100644
--- a/app/Locales/es_ES/translations.php
+++ b/app/Locales/es_ES/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/fi_FI/translations.php b/app/Locales/fi_FI/translations.php
index 5d05e92d..78fc85f2 100644
--- a/app/Locales/fi_FI/translations.php
+++ b/app/Locales/fi_FI/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/fr_FR/translations.php b/app/Locales/fr_FR/translations.php
index f4bffc3b..5ed8b050 100644
--- a/app/Locales/fr_FR/translations.php
+++ b/app/Locales/fr_FR/translations.php
@@ -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',
);
diff --git a/app/Locales/it_IT/translations.php b/app/Locales/it_IT/translations.php
index 5854d033..30dfc379 100644
--- a/app/Locales/it_IT/translations.php
+++ b/app/Locales/it_IT/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/pl_PL/translations.php b/app/Locales/pl_PL/translations.php
index fe76b34c..517bf8b8 100644
--- a/app/Locales/pl_PL/translations.php
+++ b/app/Locales/pl_PL/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/pt_BR/translations.php b/app/Locales/pt_BR/translations.php
index 59fcc983..a766e496 100644
--- a/app/Locales/pt_BR/translations.php
+++ b/app/Locales/pt_BR/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/ru_RU/translations.php b/app/Locales/ru_RU/translations.php
index 1f5bfea2..0d34f4d6 100644
--- a/app/Locales/ru_RU/translations.php
+++ b/app/Locales/ru_RU/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/sv_SE/translations.php b/app/Locales/sv_SE/translations.php
index 20b685ef..91af147d 100644
--- a/app/Locales/sv_SE/translations.php
+++ b/app/Locales/sv_SE/translations.php
@@ -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' => '',
);
diff --git a/app/Locales/zh_CN/translations.php b/app/Locales/zh_CN/translations.php
index 92f46ef9..91914704 100644
--- a/app/Locales/zh_CN/translations.php
+++ b/app/Locales/zh_CN/translations.php
@@ -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' => '',
);
diff --git a/app/Model/ProjectActivity.php b/app/Model/ProjectActivity.php
index d2457609..6d6ef454 100644
--- a/app/Model/ProjectActivity.php
+++ b/app/Model/ProjectActivity.php
@@ -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)
diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php
index 5bf8c139..56795152 100644
--- a/app/Model/TaskFinder.php
+++ b/app/Model/TaskFinder.php
@@ -112,6 +112,33 @@ class TaskFinder extends Base
}
/**
+ * 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
*
* @access public
diff --git a/app/Templates/app_index.php b/app/Templates/app_index.php
new file mode 100644
index 00000000..91eecce4
--- /dev/null
+++ b/app/Templates/app_index.php
@@ -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> \ No newline at end of file
diff --git a/app/Templates/layout.php b/app/Templates/layout.php
index 434c5aca..a86d613b 100644
--- a/app/Templates/layout.php
+++ b/app/Templates/layout.php
@@ -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>
diff --git a/app/Templates/project_activity.php b/app/Templates/project_activity.php
index 50743d68..d07ba86a 100644
--- a/app/Templates/project_activity.php
+++ b/app/Templates/project_activity.php
@@ -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> \ No newline at end of file
diff --git a/app/Templates/project_events.php b/app/Templates/project_events.php
new file mode 100644
index 00000000..1b606414
--- /dev/null
+++ b/app/Templates/project_events.php
@@ -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 ?> \ No newline at end of file
diff --git a/app/Templates/task_table.php b/app/Templates/task_table.php
index b6fdb2b9..fa04fa55 100644
--- a/app/Templates/task_table.php
+++ b/app/Templates/task_table.php
@@ -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) ?>
diff --git a/assets/css/app.css b/assets/css/app.css
index 0bb25740..a4d71cb4 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -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;
diff --git a/assets/js/app.js b/assets/js/app.js
index 395dfb6e..7dcf04eb 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -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() {
- board_load_events();
- filter_load_events();
- // Project select box
- $("#board-selector").chosen({
- width: 180
- });
+ Kanboard.Before();
- $("#board-selector").change(function() {
- window.location = "?controller=board&action=show&project_id=" + $(this).val();
- });
+ board_load_events();
+ filter_load_events();
}
};
@@ -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();
}
diff --git a/tests/units/ProjectActivityTest.php b/tests/units/ProjectActivityTest.php
index 2565b6e7..7e7841dd 100644
--- a/tests/units/ProjectActivityTest.php
+++ b/tests/units/ProjectActivityTest.php
@@ -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));