summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Gantt.php2
-rw-r--r--app/Controller/Project.php2
-rw-r--r--app/Controller/Projectuser.php136
-rw-r--r--app/Model/Acl.php1
-rw-r--r--app/Model/Project.php37
-rw-r--r--app/Model/ProjectPermission.php77
-rw-r--r--app/Model/TaskFinder.php37
-rw-r--r--app/Model/User.php11
-rw-r--r--app/Template/layout.php10
-rw-r--r--app/Template/project/index.php44
-rw-r--r--app/Template/project_user/layout.php28
-rw-r--r--app/Template/project_user/roles.php33
-rw-r--r--app/Template/project_user/sidebar.php28
-rw-r--r--app/Template/project_user/tasks.php46
-rw-r--r--app/Template/user/edit.php4
15 files changed, 455 insertions, 41 deletions
diff --git a/app/Controller/Gantt.php b/app/Controller/Gantt.php
index 1ea5e957..6f3fb5c7 100644
--- a/app/Controller/Gantt.php
+++ b/app/Controller/Gantt.php
@@ -42,7 +42,7 @@ class Gantt extends Base
*/
public function saveDate()
{
- $project = $this->getProject();
+ $this->getProject();
$values = $this->request->getJson();
$result = $this->taskModification->update(array(
diff --git a/app/Controller/Project.php b/app/Controller/Project.php
index 9309cfae..3e3e47ce 100644
--- a/app/Controller/Project.php
+++ b/app/Controller/Project.php
@@ -30,7 +30,7 @@ class Project extends Base
->setUrl('project', 'index')
->setMax(20)
->setOrder('name')
- ->setQuery($this->project->getQueryColumnStats($project_ids))
+ ->setQuery($this->project->getQueryProjectDetails($project_ids))
->calculate();
$this->response->html($this->template->layout('project/index', array(
diff --git a/app/Controller/Projectuser.php b/app/Controller/Projectuser.php
new file mode 100644
index 00000000..dba069c9
--- /dev/null
+++ b/app/Controller/Projectuser.php
@@ -0,0 +1,136 @@
+<?php
+
+namespace Controller;
+
+use Model\User as UserModel;
+use Model\Task as TaskModel;
+
+/**
+ * Project User overview
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class Projectuser extends Base
+{
+ /**
+ * Common layout for users overview views
+ *
+ * @access private
+ * @param string $template Template name
+ * @param array $params Template parameters
+ * @return string
+ */
+ private function layout($template, array $params)
+ {
+ $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
+ $params['content_for_sublayout'] = $this->template->render($template, $params);
+ $params['filter'] = array('user_id' => $params['user_id']);
+
+ return $this->template->layout('project_user/layout', $params);
+ }
+
+ private function common()
+ {
+ $user_id = $this->request->getIntegerParam('user_id', UserModel::EVERYBODY_ID);
+
+ if ($this->userSession->isAdmin()) {
+ $project_ids = $this->project->getAllIds();
+ }
+ else {
+ $project_ids = $this->projectPermission->getMemberProjectIds($this->userSession->getId());
+ }
+
+ return array($user_id, $project_ids, $this->user->getList(true));
+ }
+
+ private function role($is_owner, $action, $title, $title_user)
+ {
+ list($user_id, $project_ids, $users) = $this->common();
+
+ $query = $this->projectPermission->getQueryByRole($project_ids, $is_owner)->callback(array($this->project, 'applyColumnStats'));
+
+ if ($user_id !== UserModel::EVERYBODY_ID) {
+ $query->eq(UserModel::TABLE.'.id', $user_id);
+ $title = t($title_user, $users[$user_id]);
+ }
+
+ $paginator = $this->paginator
+ ->setUrl('projectuser', $action, array('user_id' => $user_id))
+ ->setMax(30)
+ ->setOrder('projects.name')
+ ->setQuery($query)
+ ->calculate();
+
+ $this->response->html($this->layout('project_user/roles', array(
+ 'paginator' => $paginator,
+ 'title' => $title,
+ 'action' => $action,
+ 'user_id' => $user_id,
+ 'users' => $users,
+ )));
+ }
+
+ private function tasks($is_active, $action, $title, $title_user)
+ {
+ list($user_id, $project_ids, $users) = $this->common();
+
+ $query = $this->taskFinder->getProjectUserOverviewQuery($project_ids, $is_active);
+
+ if ($user_id !== UserModel::EVERYBODY_ID) {
+ $query->eq(TaskModel::TABLE.'.owner_id', $user_id);
+ $title = t($title_user, $users[$user_id]);
+ }
+
+ $paginator = $this->paginator
+ ->setUrl('projectuser', $action, array('user_id' => $user_id))
+ ->setMax(50)
+ ->setOrder(TaskModel::TABLE.'.id')
+ ->setQuery($query)
+ ->calculate();
+
+ $this->response->html($this->layout('project_user/tasks', array(
+ 'paginator' => $paginator,
+ 'title' => $title,
+ 'action' => $action,
+ 'user_id' => $user_id,
+ 'users' => $users,
+ )));
+ }
+
+ /**
+ * Display the list of project managers
+ *
+ */
+ public function managers()
+ {
+ $this->role(1, 'managers', t('People who are project managers'), 'Projects where "%s" is manager');
+ }
+
+ /**
+ * Display the list of project members
+ *
+ */
+ public function members()
+ {
+ $this->role(0, 'members', t('People who are project members'), 'Projects where "%s" is member');
+ }
+
+ /**
+ * Display the list of open taks
+ *
+ */
+ public function opens()
+ {
+ $this->tasks(TaskModel::STATUS_OPEN, 'opens', t('Open tasks'), 'Open tasks assigned to "%s"');
+ }
+
+ /**
+ * Display the list of closed tasks
+ *
+ */
+ public function closed()
+ {
+ $this->tasks(TaskModel::STATUS_CLOSED, 'closed', t('Closed tasks'), 'Closed tasks assigned to "%s"');
+ }
+}
diff --git a/app/Model/Acl.php b/app/Model/Acl.php
index 312ae7d4..b1e9eb07 100644
--- a/app/Model/Acl.php
+++ b/app/Model/Acl.php
@@ -76,6 +76,7 @@ class Acl extends Base
*/
private $project_admin_acl = array(
'project' => array('remove'),
+ 'projectuser' => '*',
);
/**
diff --git a/app/Model/Project.php b/app/Model/Project.php
index 3c864e5d..fedc41ac 100644
--- a/app/Model/Project.php
+++ b/app/Model/Project.php
@@ -261,6 +261,24 @@ class Project extends Base
}
/**
+ * Fetch more information for each project
+ *
+ * @access public
+ * @param array $projects
+ * @return array
+ */
+ public function applyProjectDetails(array $projects)
+ {
+ foreach ($projects as &$project) {
+ $this->getColumnStats($project);
+ $project['managers'] = $this->projectPermission->getManagers($project['id']);
+ $project['members'] = $this->projectPermission->getOnlyMembers($project['id']);
+ }
+
+ return $projects;
+ }
+
+ /**
* Get project summary for a list of project
*
* @access public
@@ -280,6 +298,25 @@ class Project extends Base
}
/**
+ * Get project details (users + columns) for a list of project
+ *
+ * @access public
+ * @param array $project_ids List of project id
+ * @return \PicoDb\Table
+ */
+ public function getQueryProjectDetails(array $project_ids)
+ {
+ if (empty($project_ids)) {
+ return $this->db->table(Project::TABLE)->limit(0);
+ }
+
+ return $this->db
+ ->table(Project::TABLE)
+ ->in('id', $project_ids)
+ ->callback(array($this, 'applyProjectDetails'));
+ }
+
+ /**
* Create a project
*
* @access public
diff --git a/app/Model/ProjectPermission.php b/app/Model/ProjectPermission.php
index bc752dda..03e9bea6 100644
--- a/app/Model/ProjectPermission.php
+++ b/app/Model/ProjectPermission.php
@@ -66,18 +66,19 @@ class ProjectPermission extends Base
}
/**
- * Get a list of people associated to the project
+ * Get a list of standard user members for a project
*
* @access public
* @param integer $project_id Project id
* @return array
*/
- public function getAssociatedUsers($project_id)
+ public function getOnlyMembers($project_id)
{
$users = $this->db
->table(self::TABLE)
->join(User::TABLE, 'id', 'user_id')
->eq('project_id', $project_id)
+ ->eq('is_owner', 0)
->asc('username')
->columns(User::TABLE.'.id', User::TABLE.'.username', User::TABLE.'.name')
->findAll();
@@ -107,6 +108,57 @@ class ProjectPermission extends Base
}
/**
+ * Get query for project users overview
+ *
+ * @access public
+ * @param array $project_ids
+ * @param integer $is_owner
+ * @return \PicoDb\Table
+ */
+ public function getQueryByRole(array $project_ids, $is_owner = 0)
+ {
+ if (empty($project_ids)) {
+ $project_ids = array(-1);
+ }
+
+ return $this
+ ->db
+ ->table(self::TABLE)
+ ->join(User::TABLE, 'id', 'user_id')
+ ->join(Project::TABLE, 'id', 'project_id')
+ ->eq(self::TABLE.'.is_owner', $is_owner)
+ ->eq(Project::TABLE.'.is_private', 0)
+ ->in(Project::TABLE.'.id', $project_ids)
+ ->columns(
+ User::TABLE.'.id',
+ User::TABLE.'.username',
+ User::TABLE.'.name',
+ Project::TABLE.'.name AS project_name',
+ Project::TABLE.'.id'
+ );
+ }
+
+ /**
+ * Get a list of people associated to the project
+ *
+ * @access public
+ * @param integer $project_id Project id
+ * @return array
+ */
+ public function getAssociatedUsers($project_id)
+ {
+ $users = $this->db
+ ->table(self::TABLE)
+ ->join(User::TABLE, 'id', 'user_id')
+ ->eq('project_id', $project_id)
+ ->asc('username')
+ ->columns(User::TABLE.'.id', User::TABLE.'.username', User::TABLE.'.name')
+ ->findAll();
+
+ return $this->user->prepareList($users);
+ }
+
+ /**
* Get allowed and not allowed users for a project
*
* @access public
@@ -127,7 +179,6 @@ class ProjectPermission extends Base
$users['managers'] = $this->getManagers($project_id);
foreach ($all_users as $user_id => $username) {
-
if (! isset($users['allowed'][$user_id])) {
$users['not_allowed'][$user_id] = $username;
}
@@ -270,26 +321,6 @@ class ProjectPermission extends Base
}
/**
- * Filter a list of projects for a given user
- *
- * @access public
- * @param array $projects Project list: ['project_id' => 'project_name']
- * @param integer $user_id User id
- * @param string $filter Method name to apply
- * @return array
- */
- public function filterProjects(array $projects, $user_id, $filter = 'isUserAllowed')
- {
- foreach ($projects as $project_id => $project_name) {
- if (! $this->$filter($project_id, $user_id)) {
- unset($projects[$project_id]);
- }
- }
-
- return $projects;
- }
-
- /**
* Return a list of allowed active projects for a given user
*
* @access public
diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php
index 6cf79d1f..b98e3bd5 100644
--- a/app/Model/TaskFinder.php
+++ b/app/Model/TaskFinder.php
@@ -13,6 +13,43 @@ use PDO;
class TaskFinder extends Base
{
/**
+ * Get query for project user overview
+ *
+ * @access public
+ * @param array $project_ids
+ * @param integer $is_active
+ * @return \PicoDb\Table
+ */
+ public function getProjectUserOverviewQuery(array $project_ids, $is_active)
+ {
+ if (empty($project_ids)) {
+ $project_ids = array(-1);
+ }
+
+ return $this->db
+ ->table(Task::TABLE)
+ ->columns(
+ Task::TABLE.'.id',
+ Task::TABLE.'.title',
+ Task::TABLE.'.date_due',
+ Task::TABLE.'.date_started',
+ Task::TABLE.'.project_id',
+ Task::TABLE.'.color_id',
+ Task::TABLE.'.time_spent',
+ Task::TABLE.'.time_estimated',
+ Project::TABLE.'.name AS project_name',
+ Board::TABLE.'.title AS column_name',
+ User::TABLE.'.username AS assignee_username',
+ User::TABLE.'.name AS assignee_name'
+ )
+ ->eq(Task::TABLE.'.is_active', $is_active)
+ ->in(Project::TABLE.'.id', $project_ids)
+ ->join(Project::TABLE, 'id', 'project_id')
+ ->join(Board::TABLE, 'id', 'column_id', Task::TABLE)
+ ->join(User::TABLE, 'id', 'owner_id', Task::TABLE);
+ }
+
+ /**
* Get query for assigned user tasks
*
* @access public
diff --git a/app/Model/User.php b/app/Model/User.php
index 76af342d..1a7a0666 100644
--- a/app/Model/User.php
+++ b/app/Model/User.php
@@ -208,12 +208,19 @@ class User extends Base
* List all users (key-value pairs with id/username)
*
* @access public
+ * @param boolean $prepend Prepend "All users"
* @return array
*/
- public function getList()
+ public function getList($prepend = false)
{
$users = $this->db->table(self::TABLE)->columns('id', 'username', 'name')->findAll();
- return $this->prepareList($users);
+ $listing = $this->prepareList($users);
+
+ if ($prepend) {
+ return array(User::EVERYBODY_ID => t('Everybody')) + $listing;
+ }
+
+ return $listing;
}
/**
diff --git a/app/Template/layout.php b/app/Template/layout.php
index 7d986309..fcdc23a0 100644
--- a/app/Template/layout.php
+++ b/app/Template/layout.php
@@ -12,7 +12,7 @@
<?php endif ?>
<?php if (! isset($not_editable)): ?>
- <?= $this->asset->js('assets/js/app.js', true) ?>
+ <?= $this->asset->js('assets/js/app.js') ?>
<?php endif ?>
<?= $this->asset->colorCss() ?>
@@ -48,7 +48,13 @@
<ul>
<?php if (isset($board_selector) && ! empty($board_selector)): ?>
<li>
- <select id="board-selector" tabindex="-1" data-notfound="<?= t('No results match:') ?>" data-placeholder="<?= t('Display another project') ?>" data-board-url="<?= $this->url->href('board', 'show', array('project_id' => 'PROJECT_ID')) ?>">
+ <select id="board-selector"
+ class="chosen-select select-auto-redirect"
+ tabindex="-1"
+ data-notfound="<?= t('No results match:') ?>"
+ data-placeholder="<?= t('Display another project') ?>"
+ data-redirect-regex="PROJECT_ID"
+ data-redirect-url="<?= $this->url->href('board', 'show', array('project_id' => 'PROJECT_ID')) ?>">
<option value=""></option>
<?php foreach($board_selector as $board_id => $board_name): ?>
<option value="<?= $board_id ?>"><?= $this->e($board_name) ?></option>
diff --git a/app/Template/project/index.php b/app/Template/project/index.php
index 1fb3b5d6..96e359b6 100644
--- a/app/Template/project/index.php
+++ b/app/Template/project/index.php
@@ -5,18 +5,24 @@
<li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('New project'), 'project', 'create') ?></li>
<?php endif ?>
<li><i class="fa fa-lock fa-fw"></i><?= $this->url->link(t('New private project'), 'project', 'create', array('private' => 1)) ?></li>
+ <?php if ($this->user->isProjectAdmin() || $this->user->isAdmin()): ?>
+ <li><i class="fa fa-users fa-fw"></i><?= $this->url->link(t('Users overview'), 'projectuser', 'managers') ?></li>
+ <?php endif ?>
</ul>
</div>
<section>
<?php if ($paginator->isEmpty()): ?>
<p class="alert"><?= t('No project') ?></p>
<?php else: ?>
- <table class="table-fixed">
+ <table class="table-stripped">
<tr>
- <th class="column-8"><?= $paginator->order(t('Id'), 'id') ?></th>
- <th class="column-8"><?= $paginator->order(t('Status'), 'is_active') ?></th>
- <th class="column-8"><?= $paginator->order(t('Identifier'), 'identifier') ?></th>
+ <th class="column-5"><?= $paginator->order(t('Id'), 'id') ?></th>
+ <th class="column-5"><?= $paginator->order(t('Status'), 'is_active') ?></th>
<th class="column-20"><?= $paginator->order(t('Project'), 'name') ?></th>
+ <?php if ($this->user->isAdmin() || $this->user->isProjectAdmin()): ?>
+ <th class="column-15"><?= t('Managers') ?></th>
+ <th class="column-15"><?= t('Members') ?></th>
+ <?php endif ?>
<th><?= t('Columns') ?></th>
</tr>
<?php foreach ($paginator->getCollection() as $project): ?>
@@ -32,16 +38,14 @@
<?php endif ?>
</td>
<td>
- <?= $this->e($project['identifier']) ?>
- </td>
- <td>
- <?= $this->url->link('<i class="fa fa-th"></i>', 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Board')) ?>&nbsp;
+ <?= $this->url->link('<i class="fa fa-th"></i>', 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Board')) ?>
+ <?= $this->url->link('<i class="fa fa-sliders fa-fw"></i>', 'gantt', 'project', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Gantt chart')) ?>
<?php if ($project['is_public']): ?>
- <i class="fa fa-share-alt fa-fw"></i>
+ <i class="fa fa-share-alt fa-fw" title="<?= t('Shared project') ?>"></i>
<?php endif ?>
<?php if ($project['is_private']): ?>
- <i class="fa fa-lock fa-fw"></i>
+ <i class="fa fa-lock fa-fw" title="<?= t('Private project') ?>"></i>
<?php endif ?>
<?= $this->url->link($this->e($project['name']), 'project', 'show', array('project_id' => $project['id'])) ?>
@@ -51,6 +55,26 @@
</span>
<?php endif ?>
</td>
+ <?php if ($this->user->isAdmin() || $this->user->isProjectAdmin()): ?>
+ <td>
+ <ul>
+ <?php foreach ($project['managers'] as $user_id => $user_name): ?>
+ <li><?= $this->url->link($this->e($user_name), 'projectuser', 'opens', array('user_id' => $user_id)) ?></li>
+ <?php endforeach ?>
+ </ul>
+ </td>
+ <td>
+ <?php if ($project['is_everybody_allowed'] == 1): ?>
+ <?= t('Everybody') ?>
+ <?php else: ?>
+ <ul>
+ <?php foreach ($project['members'] as $user_id => $user_name): ?>
+ <li><?= $this->url->link($this->e($user_name), 'projectuser', 'opens', array('user_id' => $user_id)) ?></li>
+ <?php endforeach ?>
+ </ul>
+ <?php endif ?>
+ </td>
+ <?php endif ?>
<td class="dashboard-project-stats">
<?php foreach ($project['columns'] as $column): ?>
<strong title="<?= t('Task count') ?>"><?= $column['nb_tasks'] ?></strong>
diff --git a/app/Template/project_user/layout.php b/app/Template/project_user/layout.php
new file mode 100644
index 00000000..23486cb7
--- /dev/null
+++ b/app/Template/project_user/layout.php
@@ -0,0 +1,28 @@
+<section id="main">
+ <div class="page-header">
+ <ul>
+ <?php if ($this->user->isProjectAdmin() || $this->user->isAdmin()): ?>
+ <li><i class="fa fa-plus fa-fw"></i><?= $this->url->link(t('New project'), 'project', 'create') ?></li>
+ <?php endif ?>
+ <li>
+ <i class="fa fa-lock fa-fw"></i>
+ <?= $this->url->link(t('New private project'), 'project', 'create', array('private' => 1)) ?>
+ </li>
+ <li>
+ <i class="fa fa-folder fa-fw"></i>
+ <?= $this->url->link(t('All projects'), 'project', 'index') ?>
+ </li>
+ </ul>
+ </div>
+ <section class="sidebar-container">
+
+ <?= $this->render('project_user/sidebar', array('users' => $users, 'action' => $action, 'filter' => $filter)) ?>
+
+ <div class="sidebar-content">
+ <div class="page-header">
+ <h2><?= $this->e($title) ?></h2>
+ </div>
+ <?= $content_for_sublayout ?>
+ </div>
+ </section>
+</section> \ No newline at end of file
diff --git a/app/Template/project_user/roles.php b/app/Template/project_user/roles.php
new file mode 100644
index 00000000..35d16241
--- /dev/null
+++ b/app/Template/project_user/roles.php
@@ -0,0 +1,33 @@
+<?php if ($paginator->isEmpty()): ?>
+ <p class="alert"><?= t('No project') ?></p>
+<?php else: ?>
+ <table class="table-fixed">
+ <tr>
+ <th class="column-20"><?= $paginator->order(t('User'), 'users.username') ?></th>
+ <th class="column-25"><?= $paginator->order(t('Project'), 'projects.name') ?></th>
+ <th><?= t('Columns') ?></th>
+ </tr>
+ <?php foreach ($paginator->getCollection() as $project): ?>
+ <tr>
+ <td>
+ <?= $this->e($this->user->getFullname($project)) ?>
+ </td>
+ <td>
+ <?= $this->url->link('<i class="fa fa-th"></i>', 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Board')) ?>
+ <?= $this->url->link('<i class="fa fa-sliders fa-fw"></i>', 'gantt', 'project', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Gantt chart')) ?>
+ <?= $this->url->link('<i class="fa fa-cog fa-fw"></i>', 'project', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Project settings')) ?>
+
+ <?= $this->e($project['project_name']) ?>
+ </td>
+ <td class="dashboard-project-stats">
+ <?php foreach ($project['columns'] as $column): ?>
+ <strong title="<?= t('Task count') ?>"><?= $column['nb_tasks'] ?></strong>
+ <span><?= $this->e($column['title']) ?></span>
+ <?php endforeach ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+
+ <?= $paginator ?>
+<?php endif ?> \ No newline at end of file
diff --git a/app/Template/project_user/sidebar.php b/app/Template/project_user/sidebar.php
new file mode 100644
index 00000000..f57323d5
--- /dev/null
+++ b/app/Template/project_user/sidebar.php
@@ -0,0 +1,28 @@
+<div class="sidebar">
+ <h2><?= t('Actions') ?></h2>
+
+ <?= $this->form->select(
+ 'user_id',
+ $users,
+ $filter,
+ array(),
+ array('data-redirect-url="'.$this->url->href('projectuser', $action, array('user_id' => 'USER_ID')).'"', 'data-redirect-regex="USER_ID"'),
+ 'chosen-select select-auto-redirect'
+ ) ?>
+
+ <br/><br/>
+ <ul>
+ <li>
+ <?= $this->url->link(t('Project managers'), 'projectuser', 'managers', $filter) ?>
+ </li>
+ <li>
+ <?= $this->url->link(t('Project members'), 'projectuser', 'members', $filter) ?>
+ </li>
+ <li>
+ <?= $this->url->link(t('Open tasks'), 'projectuser', 'opens', $filter) ?>
+ </li>
+ <li>
+ <?= $this->url->link(t('Closed tasks'), 'projectuser', 'closed', $filter) ?>
+ </li>
+ </ul>
+</div> \ No newline at end of file
diff --git a/app/Template/project_user/tasks.php b/app/Template/project_user/tasks.php
new file mode 100644
index 00000000..f4fc2723
--- /dev/null
+++ b/app/Template/project_user/tasks.php
@@ -0,0 +1,46 @@
+<?php if ($paginator->isEmpty()): ?>
+ <p class="alert"><?= t('No tasks found.') ?></p>
+<?php elseif (! $paginator->isEmpty()): ?>
+ <table class="table-small">
+ <tr>
+ <th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
+ <th class="column-10"><?= $paginator->order(t('Project'), 'projects.name') ?></th>
+ <th class="column-15"><?= $paginator->order(t('Column'), 'tasks.column_id') ?></th>
+ <th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
+ <th class="column-15"><?= $paginator->order(t('Assignee'), 'users.username') ?></th>
+ <th class="column-15"><?= $paginator->order(t('Start date'), 'tasks.date_started') ?></th>
+ <th class="column-15"><?= $paginator->order(t('Due date'), 'tasks.date_due') ?></th>
+ </tr>
+ <?php foreach ($paginator->getCollection() as $task): ?>
+ <tr>
+ <td class="task-table color-<?= $task['color_id'] ?>">
+ <?= $this->url->link('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
+ </td>
+ <td>
+ <?= $this->url->link($this->e($task['project_name']), 'board', 'show', array('project_id' => $task['project_id'])) ?>
+ </td>
+ <td>
+ <?= $this->e($task['column_name']) ?>
+ </td>
+ <td>
+ <?= $this->url->link($this->e($task['title']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
+ </td>
+ <td>
+ <?php if ($task['assignee_username']): ?>
+ <?= $this->e($task['assignee_name'] ?: $task['assignee_username']) ?>
+ <?php else: ?>
+ <?= t('Unassigned') ?>
+ <?php endif ?>
+ </td>
+ <td>
+ <?= dt('%B %e, %Y', $task['date_started']) ?>
+ </td>
+ <td>
+ <?= dt('%B %e, %Y', $task['date_due']) ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+
+ <?= $paginator ?>
+<?php endif ?>
diff --git a/app/Template/user/edit.php b/app/Template/user/edit.php
index a60ee681..cd10b2ab 100644
--- a/app/Template/user/edit.php
+++ b/app/Template/user/edit.php
@@ -23,8 +23,8 @@
<?= $this->form->select('language', $languages, $values, $errors) ?><br/>
<?php if ($this->user->isAdmin()): ?>
- <?= $this->form->checkbox('is_admin', t('Administrator'), 1, isset($values['is_admin']) && $values['is_admin'] == 1) ?><br/>
- <?= $this->form->checkbox('is_project_admin', t('Project Administrator'), 1, isset($values['is_project_admin']) && $values['is_project_admin'] == 1) ?><br/>
+ <?= $this->form->checkbox('is_admin', t('Administrator'), 1, isset($values['is_admin']) && $values['is_admin'] == 1) ?>
+ <?= $this->form->checkbox('is_project_admin', t('Project Administrator'), 1, isset($values['is_project_admin']) && $values['is_project_admin'] == 1) ?>
<?php endif ?>
<div class="form-actions">