summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Core/Listener.php4
-rw-r--r--app/Core/Request.php69
-rw-r--r--app/Core/Response.php99
-rw-r--r--app/Core/Router.php2
-rw-r--r--app/Core/Session.php39
-rw-r--r--app/Core/Translator.php2
-rw-r--r--app/Model/Action.php2
-rw-r--r--app/Model/Category.php4
-rw-r--r--app/Model/Config.php4
-rw-r--r--app/Model/File.php5
-rw-r--r--app/Model/Project.php6
-rw-r--r--app/Templates/board_public.php49
-rw-r--r--app/Templates/board_show.php53
-rw-r--r--app/Templates/board_task.php76
-rw-r--r--app/Templates/project_search.php64
-rw-r--r--app/Templates/project_tasks.php56
-rw-r--r--app/Templates/task_table.php54
-rw-r--r--assets/css/app.css126
-rw-r--r--assets/js/board.js4
19 files changed, 412 insertions, 306 deletions
diff --git a/app/Core/Listener.php b/app/Core/Listener.php
index b8bdd680..0df641ba 100644
--- a/app/Core/Listener.php
+++ b/app/Core/Listener.php
@@ -11,6 +11,10 @@ namespace Core;
interface Listener {
/**
+ * Execute the listener
+ *
+ * @access public
+ * @param array $data Event data
* @return boolean
*/
public function execute(array $data);
diff --git a/app/Core/Request.php b/app/Core/Request.php
index df8ea41a..7e9f24ac 100644
--- a/app/Core/Request.php
+++ b/app/Core/Request.php
@@ -2,39 +2,92 @@
namespace Core;
+/**
+ * Request class
+ *
+ * @package core
+ * @author Frederic Guillot
+ */
class Request
{
+ /**
+ * Get URL string parameter
+ *
+ * @access public
+ * @param string $name Parameter name
+ * @param string $default_value Default value
+ * @return string
+ */
public function getStringParam($name, $default_value = '')
{
return isset($_GET[$name]) ? $_GET[$name] : $default_value;
}
+ /**
+ * Get URL integer parameter
+ *
+ * @access public
+ * @param string $name Parameter name
+ * @param integer $default_value Default value
+ * @return integer
+ */
public function getIntegerParam($name, $default_value = 0)
{
return isset($_GET[$name]) && ctype_digit($_GET[$name]) ? (int) $_GET[$name] : $default_value;
}
+ /**
+ * Get a form value
+ *
+ * @access public
+ * @param string $name Form field name
+ * @return string|null
+ */
public function getValue($name)
{
$values = $this->getValues();
return isset($values[$name]) ? $values[$name] : null;
}
+ /**
+ * Get form values or unserialized json request
+ *
+ * @access public
+ * @return array
+ */
public function getValues()
{
- if (! empty($_POST)) return $_POST;
+ if (! empty($_POST)) {
+ return $_POST;
+ }
$result = json_decode($this->getBody(), true);
- if ($result) return $result;
+
+ if ($result) {
+ return $result;
+ }
return array();
}
+ /**
+ * Get the raw body of the HTTP request
+ *
+ * @access public
+ * @return string
+ */
public function getBody()
{
return file_get_contents('php://input');
}
+ /**
+ * Get the content of an uploaded file
+ *
+ * @access public
+ * @param string $name Form file name
+ * @return string
+ */
public function getFileContent($name)
{
if (isset($_FILES[$name])) {
@@ -44,11 +97,23 @@ class Request
return '';
}
+ /**
+ * Return true if the HTTP request is sent with the POST method
+ *
+ * @access public
+ * @return bool
+ */
public function isPost()
{
return isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST';
}
+ /**
+ * Return true if the HTTP request is an Ajax request
+ *
+ * @access public
+ * @return bool
+ */
public function isAjax()
{
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
diff --git a/app/Core/Response.php b/app/Core/Response.php
index ee98c9ed..87d2fa4a 100644
--- a/app/Core/Response.php
+++ b/app/Core/Response.php
@@ -2,20 +2,41 @@
namespace Core;
+/**
+ * Response class
+ *
+ * @package core
+ * @author Frederic Guillot
+ */
class Response
{
+ /**
+ * Send a custom Content-Type header
+ *
+ * @access public
+ * @param string $mimetype Mime-type
+ */
public function contentType($mimetype)
{
header('Content-Type: '.$mimetype);
}
+ /**
+ * Force the browser to download an attachment
+ *
+ * @access public
+ * @param string $filename File name
+ */
public function forceDownload($filename)
{
header('Content-Disposition: attachment; filename="'.$filename.'"');
}
/**
- * @param integer $status_code
+ * Send a custom HTTP status code
+ *
+ * @access public
+ * @param integer $status_code HTTP status code
*/
public function status($status_code)
{
@@ -23,12 +44,25 @@ class Response
header($_SERVER['SERVER_PROTOCOL'].' '.$status_code);
}
+ /**
+ * Redirect to another URL
+ *
+ * @access public
+ * @param string $url Redirection URL
+ */
public function redirect($url)
{
header('Location: '.$url);
exit;
}
+ /**
+ * Send a Json response
+ *
+ * @access public
+ * @param array $data Data to serialize in json
+ * @param integer $status_code HTTP status code
+ */
public function json(array $data, $status_code = 200)
{
$this->status($status_code);
@@ -39,6 +73,13 @@ class Response
exit;
}
+ /**
+ * Send a text response
+ *
+ * @access public
+ * @param string $data Raw data
+ * @param integer $status_code HTTP status code
+ */
public function text($data, $status_code = 200)
{
$this->status($status_code);
@@ -49,6 +90,13 @@ class Response
exit;
}
+ /**
+ * Send a HTML response
+ *
+ * @access public
+ * @param string $data Raw data
+ * @param integer $status_code HTTP status code
+ */
public function html($data, $status_code = 200)
{
$this->status($status_code);
@@ -59,6 +107,13 @@ class Response
exit;
}
+ /**
+ * Send a XML response
+ *
+ * @access public
+ * @param string $data Raw data
+ * @param integer $status_code HTTP status code
+ */
public function xml($data, $status_code = 200)
{
$this->status($status_code);
@@ -69,6 +124,13 @@ class Response
exit;
}
+ /**
+ * Send a javascript response
+ *
+ * @access public
+ * @param string $data Raw data
+ * @param integer $status_code HTTP status code
+ */
public function js($data, $status_code = 200)
{
$this->status($status_code);
@@ -79,6 +141,13 @@ class Response
exit;
}
+ /**
+ * Send a binary response
+ *
+ * @access public
+ * @param string $data Raw data
+ * @param integer $status_code HTTP status code
+ */
public function binary($data, $status_code = 200)
{
$this->status($status_code);
@@ -90,6 +159,12 @@ class Response
exit;
}
+ /**
+ * Send the security header: Content-Security-Policy
+ *
+ * @access public
+ * @param array $policies CSP rules
+ */
public function csp(array $policies = array())
{
$policies['default-src'] = "'self'";
@@ -119,16 +194,31 @@ class Response
header('Content-Security-Policy: '.$values);
}
+ /**
+ * Send the security header: X-Content-Type-Options
+ *
+ * @access public
+ */
public function nosniff()
{
header('X-Content-Type-Options: nosniff');
}
+ /**
+ * Send the security header: X-XSS-Protection
+ *
+ * @access public
+ */
public function xss()
{
header('X-XSS-Protection: 1; mode=block');
}
+ /**
+ * Send the security header: Strict-Transport-Security (only if we use HTTPS)
+ *
+ * @access public
+ */
public function hsts()
{
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
@@ -136,6 +226,13 @@ class Response
}
}
+ /**
+ * Send the security header: X-Frame-Options (deny by default)
+ *
+ * @access public
+ * @param string $mode Frame option mode
+ * @param array $urls Allowed urls for the given mode
+ */
public function xframe($mode = 'DENY', array $urls = array())
{
header('X-Frame-Options: '.$mode.' '.implode(' ', $urls));
diff --git a/app/Core/Router.php b/app/Core/Router.php
index a7c9764c..40610996 100644
--- a/app/Core/Router.php
+++ b/app/Core/Router.php
@@ -38,7 +38,7 @@ class Router
* Constructor
*
* @access public
- * @param Core\Registry $registry Registry instance
+ * @param Registry $registry Registry instance
* @param string $controller Controller name
* @param string $action Action name
*/
diff --git a/app/Core/Session.php b/app/Core/Session.php
index 0c3ec2d9..6ce1bd40 100644
--- a/app/Core/Session.php
+++ b/app/Core/Session.php
@@ -2,13 +2,33 @@
namespace Core;
+/**
+ * Session class
+ *
+ * @package core
+ * @author Frederic Guillot
+ */
class Session
{
+ /**
+ * Sesion lifetime
+ *
+ * @var integer
+ */
const SESSION_LIFETIME = 86400; // 1 day
+ /**
+ * Open a session
+ *
+ * @access public
+ * @param string $base_path Cookie path
+ * @param string $save_path Custom session save path
+ */
public function open($base_path = '/', $save_path = '')
{
- if ($save_path !== '') session_save_path($save_path);
+ if ($save_path !== '') {
+ session_save_path($save_path);
+ }
// HttpOnly and secure flags for session cookie
session_set_cookie_params(
@@ -39,16 +59,33 @@ class Session
}
}
+ /**
+ * Destroy the session
+ *
+ * @access public
+ */
public function close()
{
session_destroy();
}
+ /**
+ * Register a flash message (success notification)
+ *
+ * @access public
+ * @param string $message Message
+ */
public function flash($message)
{
$_SESSION['flash_message'] = $message;
}
+ /**
+ * Register a flash error message (error notification)
+ *
+ * @access public
+ * @param string $message Message
+ */
public function flashError($message)
{
$_SESSION['flash_error_message'] = $message;
diff --git a/app/Core/Translator.php b/app/Core/Translator.php
index be0be66a..015a76cb 100644
--- a/app/Core/Translator.php
+++ b/app/Core/Translator.php
@@ -121,7 +121,7 @@ class Translator
* Get an identifier from the translations or return the default
*
* @access public
- * @param string $idendifier Locale identifier
+ * @param string $identifier Locale identifier
* @param string $default Default value
* @return string
*/
diff --git a/app/Model/Action.php b/app/Model/Action.php
index d1b97ebc..7cd917e9 100644
--- a/app/Model/Action.php
+++ b/app/Model/Action.php
@@ -213,7 +213,7 @@ class Action extends Base
* @access public
* @param string $name Action class name
* @param integer $project_id Project id
- * @return mixed Action Instance
+ * @return \Core\Listener Action Instance
* @throw LogicException
*/
public function load($name, $project_id)
diff --git a/app/Model/Category.php b/app/Model/Category.php
index 9be37f9d..58eba403 100644
--- a/app/Model/Category.php
+++ b/app/Model/Category.php
@@ -106,7 +106,7 @@ class Category extends Base
* Validate category creation
*
* @access public
- * @param array $array Form values
+ * @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateCreation(array $values)
@@ -128,7 +128,7 @@ class Category extends Base
* Validate category modification
*
* @access public
- * @param array $array Form values
+ * @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateModification(array $values)
diff --git a/app/Model/Config.php b/app/Model/Config.php
index 994f0bc8..9748f38e 100644
--- a/app/Model/Config.php
+++ b/app/Model/Config.php
@@ -57,9 +57,9 @@ class Config extends Base
* Get a config variable from the session or the database
*
* @access public
- * @param string $name Parameter name
+ * @param string $name Parameter name
* @param string $default_value Default value of the parameter
- * @return mixed
+ * @return string
*/
public function get($name, $default_value = '')
{
diff --git a/app/Model/File.php b/app/Model/File.php
index b7015acc..41ecfba1 100644
--- a/app/Model/File.php
+++ b/app/Model/File.php
@@ -2,9 +2,6 @@
namespace Model;
-use SimpleValidator\Validator;
-use SimpleValidator\Validators;
-
/**
* File model
*
@@ -111,7 +108,7 @@ class File extends Base
* @param integer $project_id Project id
* @param integer $task_id Task id
* @param string $filename Filename
- * @return bool
+ * @return string
*/
public function generatePath($project_id, $task_id, $filename)
{
diff --git a/app/Model/Project.php b/app/Model/Project.php
index 85294830..9fbb0806 100644
--- a/app/Model/Project.php
+++ b/app/Model/Project.php
@@ -473,7 +473,7 @@ class Project extends Base
* Validate project creation
*
* @access public
- * @param array $array Form values
+ * @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateCreation(array $values)
@@ -494,7 +494,7 @@ class Project extends Base
* Validate project modification
*
* @access public
- * @param array $array Form values
+ * @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateModification(array $values)
@@ -517,7 +517,7 @@ class Project extends Base
* Validate allowed users
*
* @access public
- * @param array $array Form values
+ * @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateUserAccess(array $values)
diff --git a/app/Templates/board_public.php b/app/Templates/board_public.php
index 0808079e..f90dc01b 100644
--- a/app/Templates/board_public.php
+++ b/app/Templates/board_public.php
@@ -19,54 +19,9 @@
<?php foreach ($columns as $column): ?>
<td class="column <?= $column['task_limit'] && count($column['tasks']) > $column['task_limit'] ? 'task-limit-warning' : '' ?>">
<?php foreach ($column['tasks'] as $task): ?>
- <div class="task task-<?= $task['color_id'] ?>">
+ <div class="task-board task-<?= $task['color_id'] ?>">
- #<?= $task['id'] ?> -
-
- <span class="task-user">
- <?php if (! empty($task['owner_id'])): ?>
- <?= t('Assigned to %s', $task['username']) ?>
- <?php else: ?>
- <span class="task-nobody"><?= t('Nobody assigned') ?></span>
- <?php endif ?>
- </span>
-
- <?php if ($task['score']): ?>
- <span class="task-score"><?= Helper\escape($task['score']) ?></span>
- <?php endif ?>
-
- <div class="task-title">
- <?= Helper\escape($task['title']) ?>
- </div>
-
- <?php if ($task['category_id']): ?>
- <div class="task-category-container">
- <span class="task-category">
- <?= Helper\in_list($task['category_id'], $categories) ?>
- </span>
- </div>
- <?php endif ?>
-
- <?php if (! empty($task['date_due']) || ! empty($task['nb_comments']) || ! empty($task['description'])): ?>
- <div class="task-footer">
-
- <?php if (! empty($task['date_due'])): ?>
- <div class="task-date">
- <?= dt('%B %e, %G', $task['date_due']) ?>
- </div>
- <?php endif ?>
-
- <div class="task-icons">
- <?php if (! empty($task['nb_comments'])): ?>
- <?= $task['nb_comments'] ?> <i class="fa fa-comment-o" title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>"></i>
- <?php endif ?>
-
- <?php if (! empty($task['description'])): ?>
- <i class="fa fa-file-text-o" title="<?= t('Description') ?>"></i>
- <?php endif ?>
- </div>
- </div>
- <?php endif ?>
+ <?= Helper\template('board_task', array('task' => $task, 'categories' => $categories, 'not_editable' => true)) ?>
</div>
<?php endforeach ?>
diff --git a/app/Templates/board_show.php b/app/Templates/board_show.php
index 78f9dd50..e5cd9ceb 100644
--- a/app/Templates/board_show.php
+++ b/app/Templates/board_show.php
@@ -26,63 +26,14 @@
data-task-limit="<?= $column['task_limit'] ?>"
>
<?php foreach ($column['tasks'] as $task): ?>
- <div class="task draggable-item task-<?= $task['color_id'] ?>"
+ <div class="task-board draggable-item task-<?= $task['color_id'] ?>"
data-task-id="<?= $task['id'] ?>"
data-owner-id="<?= $task['owner_id'] ?>"
data-category-id="<?= $task['category_id'] ?>"
data-due-date="<?= $task['date_due'] ?>"
title="<?= t('View this task') ?>">
- <a href="?controller=task&amp;action=edit&amp;task_id=<?= $task['id'] ?>" title="<?= t('Edit this task') ?>">#<?= $task['id'] ?></a> -
-
- <span class="task-user">
- <?php if (! empty($task['owner_id'])): ?>
- <a href="?controller=board&amp;action=assign&amp;task_id=<?= $task['id'] ?>" title="<?= t('Change assignee') ?>"><?= t('Assigned to %s', $task['username']) ?></a>
- <?php else: ?>
- <a href="?controller=board&amp;action=assign&amp;task_id=<?= $task['id'] ?>" title="<?= t('Change assignee') ?>" class="task-nobody"><?= t('Nobody assigned') ?></a>
- <?php endif ?>
- </span>
-
- <?php if ($task['score']): ?>
- <span class="task-score"><?= Helper\escape($task['score']) ?></span>
- <?php endif ?>
-
- <div class="task-title">
- <a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>"><?= Helper\escape($task['title']) ?></a>
- </div>
-
- <?php if ($task['category_id']): ?>
- <div class="task-category-container">
- <span class="task-category">
- <?= Helper\in_list($task['category_id'], $categories) ?>
- </span>
- </div>
- <?php endif ?>
-
- <?php if (! empty($task['date_due']) || ! empty($task['nb_files']) || ! empty($task['nb_comments']) || ! empty($task['description'])): ?>
- <div class="task-footer">
-
- <?php if (! empty($task['date_due'])): ?>
- <div class="task-date">
- <?= dt('%B %e, %G', $task['date_due']) ?>
- </div>
- <?php endif ?>
-
- <div class="task-icons">
- <?php if (! empty($task['nb_files'])): ?>
- <?= $task['nb_files'] ?> <i class="fa fa-paperclip"></i>
- <?php endif ?>
-
- <?php if (! empty($task['nb_comments'])): ?>
- <?= $task['nb_comments'] ?> <i class="fa fa-comment-o" title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>"></i>
- <?php endif ?>
-
- <?php if (! empty($task['description'])): ?>
- <i class="fa fa-file-text-o" title="<?= t('Description') ?>"></i>
- <?php endif ?>
- </div>
- </div>
- <?php endif ?>
+ <?= Helper\template('board_task', array('task' => $task, 'categories' => $categories)) ?>
</div>
<?php endforeach ?>
diff --git a/app/Templates/board_task.php b/app/Templates/board_task.php
new file mode 100644
index 00000000..fa745ac1
--- /dev/null
+++ b/app/Templates/board_task.php
@@ -0,0 +1,76 @@
+<?php if (isset($not_editable)): ?>
+
+ #<?= $task['id'] ?> -
+
+ <span class="task-board-user">
+ <?php if (! empty($task['owner_id'])): ?>
+ <?= t('Assigned to %s', $task['username']) ?>
+ <?php else: ?>
+ <span class="task-board-nobody"><?= t('Nobody assigned') ?></span>
+ <?php endif ?>
+ </span>
+
+ <?php if ($task['score']): ?>
+ <span class="task-score"><?= Helper\escape($task['score']) ?></span>
+ <?php endif ?>
+
+ <div class="task-board-title">
+ <?= Helper\escape($task['title']) ?>
+ </div>
+
+<?php else: ?>
+
+ <a href="?controller=task&amp;action=edit&amp;task_id=<?= $task['id'] ?>" title="<?= t('Edit this task') ?>">#<?= $task['id'] ?></a> -
+
+ <span class="task-board-user">
+ <?php if (! empty($task['owner_id'])): ?>
+ <a href="?controller=board&amp;action=assign&amp;task_id=<?= $task['id'] ?>" title="<?= t('Change assignee') ?>"><?= t('Assigned to %s', $task['username']) ?></a>
+ <?php else: ?>
+ <a href="?controller=board&amp;action=assign&amp;task_id=<?= $task['id'] ?>" title="<?= t('Change assignee') ?>" class="task-board-nobody"><?= t('Nobody assigned') ?></a>
+ <?php endif ?>
+ </span>
+
+ <?php if ($task['score']): ?>
+ <span class="task-score"><?= Helper\escape($task['score']) ?></span>
+ <?php endif ?>
+
+ <div class="task-board-title">
+ <a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>"><?= Helper\escape($task['title']) ?></a>
+ </div>
+
+<?php endif ?>
+
+
+<?php if ($task['category_id']): ?>
+<div class="task-board-category-container">
+ <span class="task-board-category">
+ <?= Helper\in_list($task['category_id'], $categories) ?>
+ </span>
+</div>
+<?php endif ?>
+
+
+<?php if (! empty($task['date_due']) || ! empty($task['nb_files']) || ! empty($task['nb_comments']) || ! empty($task['description'])): ?>
+<div class="task-board-footer">
+
+ <?php if (! empty($task['date_due'])): ?>
+ <div class="task-board-date">
+ <?= dt('%B %e, %G', $task['date_due']) ?>
+ </div>
+ <?php endif ?>
+
+ <div class="task-board-icons">
+ <?php if (! empty($task['nb_files'])): ?>
+ <?= $task['nb_files'] ?> <i class="fa fa-paperclip" title="<?= t('Attachments') ?>"></i>
+ <?php endif ?>
+
+ <?php if (! empty($task['nb_comments'])): ?>
+ <?= $task['nb_comments'] ?> <i class="fa fa-comment-o" title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>"></i>
+ <?php endif ?>
+
+ <?php if (! empty($task['description'])): ?>
+ <i class="fa fa-file-text-o" title="<?= t('Description') ?>"></i>
+ <?php endif ?>
+ </div>
+</div>
+<?php endif ?> \ No newline at end of file
diff --git a/app/Templates/project_search.php b/app/Templates/project_search.php
index 3594fd09..7826ba63 100644
--- a/app/Templates/project_search.php
+++ b/app/Templates/project_search.php
@@ -24,69 +24,7 @@
<?php if (empty($tasks) && ! empty($values['search'])): ?>
<p class="alert"><?= t('Nothing found.') ?></p>
<?php elseif (! empty($tasks)): ?>
- <table>
- <tr>
- <th><?= t('Id') ?></th>
- <th><?= t('Column') ?></th>
- <th><?= t('Category') ?></th>
- <th><?= t('Title') ?></th>
- <th><?= t('Assignee') ?></th>
- <th><?= t('Due date') ?></th>
- <th><?= t('Date created') ?></th>
- <th><?= t('Date completed') ?></th>
- <th><?= t('Status') ?></th>
- </tr>
- <?php foreach ($tasks as $task): ?>
- <tr>
- <td class="task 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>
- </td>
- <td>
- <?= Helper\in_list($task['column_id'], $columns) ?>
- </td>
- <td>
- <?= Helper\in_list($task['category_id'], $categories, '') ?>
- </td>
- <td>
- <a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>"><?= Helper\escape($task['title']) ?></a>
- <div class="task-table-icons">
- <?php if (! empty($task['nb_comments'])): ?>
- <?= $task['nb_comments'] ?> <i class="fa fa-comment-o" title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>"></i>
- <?php endif ?>
-
- <?php if (! empty($task['description'])): ?>
- <i class="fa fa-file-text-o" title="<?= t('Description') ?>"></i>
- <?php endif ?>
- </div>
- </td>
- <td>
- <?php if ($task['username']): ?>
- <?= Helper\escape($task['username']) ?>
- <?php else: ?>
- <?= t('Unassigned') ?>
- <?php endif ?>
- </td>
- <td>
- <?= dt('%B %e, %G', $task['date_due']) ?>
- </td>
- <td>
- <?= dt('%B %e, %G at %k:%M %p', $task['date_creation']) ?>
- </td>
- <td>
- <?php if ($task['date_completed']): ?>
- <?= dt('%B %e, %G at %k:%M %p', $task['date_completed']) ?>
- <?php endif ?>
- </td>
- <td>
- <?php if ($task['is_active'] == \Model\Task::STATUS_OPEN): ?>
- <?= t('Open') ?>
- <?php else: ?>
- <?= t('Closed') ?>
- <?php endif ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
+ <?= Helper\template('task_table', array('tasks' => $tasks, 'categories' => $categories, 'columns' => $columns)) ?>
<?php endif ?>
</section>
diff --git a/app/Templates/project_tasks.php b/app/Templates/project_tasks.php
index 9f4263b8..a820be13 100644
--- a/app/Templates/project_tasks.php
+++ b/app/Templates/project_tasks.php
@@ -11,61 +11,7 @@
<?php if (empty($tasks)): ?>
<p class="alert"><?= t('No task') ?></p>
<?php else: ?>
- <table>
- <tr>
- <th><?= t('Id') ?></th>
- <th><?= t('Column') ?></th>
- <th><?= t('Category') ?></th>
- <th><?= t('Title') ?></th>
- <th><?= t('Assignee') ?></th>
- <th><?= t('Due date') ?></th>
- <th><?= t('Date created') ?></th>
- <th><?= t('Date completed') ?></th>
- </tr>
- <?php foreach ($tasks as $task): ?>
- <tr>
- <td class="task 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>
- </td>
- <td>
- <?= Helper\in_list($task['column_id'], $columns) ?>
- </td>
- <td>
- <?= Helper\in_list($task['category_id'], $categories, '') ?>
- </td>
- <td>
- <a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>"><?= Helper\escape($task['title']) ?></a>
- <div class="task-table-icons">
- <?php if (! empty($task['nb_comments'])): ?>
- <?= $task['nb_comments'] ?> <i class="fa fa-comment-o" title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>"></i>
- <?php endif ?>
-
- <?php if (! empty($task['description'])): ?>
- <i class="fa fa-file-text-o" title="<?= t('Description') ?>"></i>
- <?php endif ?>
- </div>
- </td>
- <td>
- <?php if ($task['username']): ?>
- <?= Helper\escape($task['username']) ?>
- <?php else: ?>
- <?= t('Unassigned') ?>
- <?php endif ?>
- </td>
- <td>
- <?= dt('%B %e, %G', $task['date_due']) ?>
- </td>
- <td>
- <?= dt('%B %e, %G at %k:%M %p', $task['date_creation']) ?>
- </td>
- <td>
- <?php if ($task['date_completed']): ?>
- <?= dt('%B %e, %G at %k:%M %p', $task['date_completed']) ?>
- <?php endif ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
+ <?= Helper\template('task_table', array('tasks' => $tasks, 'categories' => $categories, 'columns' => $columns)) ?>
<?php endif ?>
</section>
</section> \ No newline at end of file
diff --git a/app/Templates/task_table.php b/app/Templates/task_table.php
new file mode 100644
index 00000000..10f79d29
--- /dev/null
+++ b/app/Templates/task_table.php
@@ -0,0 +1,54 @@
+<table>
+ <tr>
+ <th><?= t('Id') ?></th>
+ <th><?= t('Column') ?></th>
+ <th><?= t('Category') ?></th>
+ <th><?= t('Title') ?></th>
+ <th><?= t('Assignee') ?></th>
+ <th><?= t('Due date') ?></th>
+ <th><?= t('Date created') ?></th>
+ <th><?= t('Date completed') ?></th>
+ <th><?= t('Status') ?></th>
+ </tr>
+ <?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>
+ </td>
+ <td>
+ <?= Helper\in_list($task['column_id'], $columns) ?>
+ </td>
+ <td>
+ <?= Helper\in_list($task['category_id'], $categories, '') ?>
+ </td>
+ <td>
+ <a href="?controller=task&amp;action=show&amp;task_id=<?= $task['id'] ?>" title="<?= t('View this task') ?>"><?= Helper\escape($task['title']) ?></a>
+ </td>
+ <td>
+ <?php if ($task['username']): ?>
+ <?= Helper\escape($task['username']) ?>
+ <?php else: ?>
+ <?= t('Unassigned') ?>
+ <?php endif ?>
+ </td>
+ <td>
+ <?= dt('%B %e, %G', $task['date_due']) ?>
+ </td>
+ <td>
+ <?= dt('%B %e, %G at %k:%M %p', $task['date_creation']) ?>
+ </td>
+ <td>
+ <?php if ($task['date_completed']): ?>
+ <?= dt('%B %e, %G at %k:%M %p', $task['date_completed']) ?>
+ <?php endif ?>
+ </td>
+ <td>
+ <?php if ($task['is_active'] == \Model\Task::STATUS_OPEN): ?>
+ <?= t('Open') ?>
+ <?php else: ?>
+ <?= t('Closed') ?>
+ <?php endif ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+</table> \ No newline at end of file
diff --git a/assets/css/app.css b/assets/css/app.css
index 78fc29bd..fcfe6b1a 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -478,7 +478,7 @@ nav .active a {
padding-left: 0;
}
-/* boards */
+/* board */
.page-header.board {
margin-bottom: 0;
}
@@ -506,6 +506,11 @@ nav .active a {
font-size: 0.8em;
}
+a.filter-on {
+ font-weight: bold;
+ color: #333;
+}
+
.public-board {
margin-top: 5px;
}
@@ -523,32 +528,67 @@ nav .active a {
background-color: red;
}
-a.filter-on {
+.draggable-item {
+ cursor: pointer;
+ user-select: none;
+}
+
+.draggable-placeholder {
+ border: 2px dashed #000;
+ background: #fafafa;
+ height: 70px;
+ margin-bottom: 10px;
+}
+
+/* task inside the board */
+.task-board {
+ position: relative;
+ margin-right: 5px;
+ margin-bottom: 10px;
+ border: 1px solid #000;
+ padding: 5px;
+ font-size: 95%;
+}
+
+.task-table a,
+.task-board a {
+ color: #000;
+ text-decoration: none;
font-weight: bold;
- color: #333;
}
-.task-title {
+.task-table a:focus,
+.task-table a:hover,
+.task-board a:focus,
+.task-board a:hover {
+ text-decoration: underline;
+}
+
+.task-board-title {
margin-top: 10px;
font-size: 110%;
}
-.task-user {
+.task-board-title a {
+ font-weight: normal;
+}
+
+.task-board-user {
font-size: 80%;
}
-.task a.task-nobody {
+a.task-board-nobody {
font-weight: normal;
font-style: italic;
color: #444;
}
-.task-category-container {
+.task-board-category-container {
text-align: right;
padding-bottom: 2px;
}
-.task-category {
+.task-board-category {
font-weight: bold;
font-size: 0.8em;
color: #000;
@@ -559,7 +599,11 @@ a.filter-on {
padding-left: 5px;
}
-.task-date {
+.task-board-footer {
+ height: 18px;
+}
+
+.task-board-date {
position: absolute;
bottom: 0;
left: 5px;
@@ -567,82 +611,24 @@ a.filter-on {
color: #D90000;
}
-.task-icons {
+.task-board-icons {
position: absolute;
bottom: 0;
right: 5px;
}
-.task-footer {
- height: 18px;
-}
-
-.task {
- border: 1px solid #000;
- padding: 5px;
- font-size: 95%;
-}
-
-td.over {
- background-color: #f0f0f0;
-}
-
-td div.over {
- border: 2px dashed #000;
-}
-
-.draggable-item {
- cursor: pointer;
- user-select: none;
-}
-
-.draggable-placeholder {
- border: 2px dashed #000;
- background: #fafafa;
- height: 70px;
- margin-bottom: 10px;
-}
-
-tr td.task a,
-div.task a {
- color: #000;
- text-decoration: none;
- font-weight: bold;
-}
-
-tr td.task a:focus,
-tr td.task a:hover,
-div.task a:focus,
-div.task a:hover {
- text-decoration: underline;
-}
-
-div.task-title a {
- font-weight: normal;
-}
-
-div.task {
- position: relative;
- margin-right: 5px;
- margin-bottom: 10px;
-}
-
+/* task score */
.task-score {
font-weight: bold;
position: absolute;
}
-div.task .task-score {
+.task-board .task-score {
font-size: 1.5em;
right: 5px;
top: 0;
}
-.task-table-icons {
- float: right ;
- text-align: right;
-}
-
/* task view */
.task-show {
position: relative;
diff --git a/assets/js/board.js b/assets/js/board.js
index 357849e6..f5547310 100644
--- a/assets/js/board.js
+++ b/assets/js/board.js
@@ -15,7 +15,7 @@
});
// Open assignee popover
- $(".task-user a").click(function(e) {
+ $(".task-boad-user a").click(function(e) {
e.preventDefault();
e.stopPropagation();
@@ -60,7 +60,7 @@
$(".column").each(function() {
var columnId = $(this).attr("data-column-id");
- $("#column-" + columnId + " .task").each(function(index) {
+ $("#column-" + columnId + " .task-board").each(function(index) {
data.push({
"task_id": parseInt($(this).attr("data-task-id")),
"position": index + 1,