diff options
-rw-r--r-- | assets/css/app.css | 4 | ||||
-rw-r--r-- | assets/js/board.js | 17 | ||||
-rw-r--r-- | controllers/base.php | 5 | ||||
-rw-r--r-- | controllers/board.php | 21 | ||||
-rw-r--r-- | locales/fr_FR/translations.php | 3 | ||||
-rw-r--r-- | locales/pl_PL/translations.php | 5 | ||||
-rw-r--r-- | models/base.php | 3 | ||||
-rw-r--r-- | models/board.php | 8 | ||||
-rw-r--r-- | models/schema.php | 13 | ||||
-rw-r--r-- | templates/board_edit.php | 7 | ||||
-rw-r--r-- | templates/board_index.php | 16 | ||||
-rw-r--r-- | templates/board_public.php | 5 | ||||
-rw-r--r-- | vendor/SimpleValidator/Validators/GreaterThan.php | 36 |
13 files changed, 118 insertions, 25 deletions
diff --git a/assets/css/app.css b/assets/css/app.css index 123ad305..14e77508 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -445,6 +445,10 @@ nav .active a { vertical-align: top; } +#board td.task-limit-warning { + background-color: red; +} + .task-title { margin-top: 10px; font-size: 110%; diff --git a/assets/js/board.js b/assets/js/board.js index a9bd35d1..4620b668 100644 --- a/assets/js/board.js +++ b/assets/js/board.js @@ -111,6 +111,23 @@ [].forEach.call(cols, function(col) { + var task_limit = col.getAttribute("data-task-limit"); + + if (task_limit != "") { + + task_limit = parseInt(task_limit); + + if (col.children.length > task_limit) { + col.classList.add("task-limit-warning"); + } + else { + col.classList.remove("task-limit-warning"); + } + + var counter = document.getElementById("task-number-column-" + col.getAttribute("data-column-id")); + if (counter) counter.innerHTML = col.children.length; + } + [].forEach.call(col.children, function(item) { data.push({ diff --git a/controllers/base.php b/controllers/base.php index c7e59b18..a59220d3 100644 --- a/controllers/base.php +++ b/controllers/base.php @@ -67,9 +67,8 @@ abstract class Base $language = $this->config->get('language', 'en_US'); if ($language !== 'en_US') \Translator\load($language); - //set timezone - $timezone = $this->config->get('timezone', 'UTC'); - date_default_timezone_set($timezone); + // Set timezone + date_default_timezone_set($this->config->get('timezone', 'UTC')); $this->response->csp(); $this->response->nosniff(); diff --git a/controllers/board.php b/controllers/board.php index 29633a14..a0f00367 100644 --- a/controllers/board.php +++ b/controllers/board.php @@ -119,11 +119,12 @@ class Board extends Base if (! $project) $this->notfound(); - $columns = $this->board->getColumnsList($project_id); + $columns = $this->board->getColumns($project_id); $values = array(); - foreach ($columns as $column_id => $column_title) { - $values['title['.$column_id.']'] = $column_title; + foreach ($columns as $column) { + $values['title['.$column['id'].']'] = $column['title']; + $values['task_limit['.$column['id'].']'] = $column['task_limit'] ?: null; } $this->response->html($this->template->layout('board_edit', array( @@ -146,19 +147,21 @@ class Board extends Base if (! $project) $this->notfound(); - $columns = $this->board->getColumnsList($project_id); + $columns = $this->board->getColumns($project_id); $data = $this->request->getValues(); - $values = array(); + $values = $columns_list = array(); - foreach ($columns as $column_id => $column_title) { - $values['title['.$column_id.']'] = isset($data['title'][$column_id]) ? $data['title'][$column_id] : ''; + foreach ($columns as $column) { + $columns_list[$column['id']] = $column['title']; + $values['title['.$column['id'].']'] = isset($data['title'][$column['id']]) ? $data['title'][$column['id']] : ''; + $values['task_limit['.$column['id'].']'] = isset($data['task_limit'][$column['id']]) ? $data['task_limit'][$column['id']] : 0; } - list($valid, $errors) = $this->board->validateModification($columns, $values); + list($valid, $errors) = $this->board->validateModification($columns_list, $values); if ($valid) { - if ($this->board->update($data['title'])) { + if ($this->board->update($data)) { $this->session->flash(t('Board updated successfully.')); $this->response->redirect('?controller=board&action=edit&project_id='.$project['id']); } diff --git a/locales/fr_FR/translations.php b/locales/fr_FR/translations.php index 6e3ef8ef..b3cbafab 100644 --- a/locales/fr_FR/translations.php +++ b/locales/fr_FR/translations.php @@ -187,4 +187,7 @@ return array( 'Sorry, I didn\'t found this information in my database!' => 'Désolé, je n\'ai pas trouvé cette information dans ma base de données !', 'Page not found' => 'Page introuvable', 'Story Points' => 'Complexité', + 'limit' => 'limite', + 'Task limit' => 'Nombre maximum de tâches', + 'This value must be greater than %d' => 'Cette valeur doit être plus grande que %d', ); diff --git a/locales/pl_PL/translations.php b/locales/pl_PL/translations.php index aaadb510..58d2323c 100644 --- a/locales/pl_PL/translations.php +++ b/locales/pl_PL/translations.php @@ -180,11 +180,14 @@ return array( '%d closed tasks' => '%d zamkniętych zadań', 'no task for this project' => 'brak zadań dla tego projektu', 'Public link' => 'Link publiczny', - 'There is no column in your project!' => 'Brak kolumnt w Twoim projekcie', + 'There is no column in your project!' => 'Brak kolumny w Twoim projekcie', 'Change assignee' => 'Zmień odpowiedzialną osobę', 'Change assignee for the task "%s"' => 'Zmień odpowiedzialną osobę dla zadania "%s"', 'Timezone' => 'Strefa czasowa', //'Sorry, I didn\'t found this information in my database!' => '', //'Page not found' => '', //'Story Points' => '', + //'limit' => '', + //'Task limit' => '', + //'This value must be greater than %d' => '', ); diff --git a/models/base.php b/models/base.php index 0a565f51..c8e4cf19 100644 --- a/models/base.php +++ b/models/base.php @@ -11,13 +11,14 @@ require __DIR__.'/../vendor/SimpleValidator/Validators/MinLength.php'; require __DIR__.'/../vendor/SimpleValidator/Validators/Integer.php'; require __DIR__.'/../vendor/SimpleValidator/Validators/Equals.php'; require __DIR__.'/../vendor/SimpleValidator/Validators/AlphaNumeric.php'; +require __DIR__.'/../vendor/SimpleValidator/Validators/GreaterThan.php'; require __DIR__.'/../vendor/PicoDb/Database.php'; require __DIR__.'/schema.php'; abstract class Base { const APP_VERSION = 'master'; - const DB_VERSION = 5; + const DB_VERSION = 6; const DB_FILENAME = 'data/db.sqlite'; private static $dbInstance = null; diff --git a/models/board.php b/models/board.php index d213f257..1a5b8b81 100644 --- a/models/board.php +++ b/models/board.php @@ -61,8 +61,10 @@ class Board extends Base { $this->db->startTransaction(); - foreach ($values as $column_id => $column_title) { - $this->db->table(self::TABLE)->eq('id', $column_id)->update(array('title' => $column_title)); + foreach (array('title', 'task_limit') as $field) { + foreach ($values[$field] as $column_id => $field_value) { + $this->db->table(self::TABLE)->eq('id', $column_id)->update(array($field => $field_value)); + } } $this->db->closeTransaction(); @@ -140,6 +142,8 @@ class Board extends Base $rules = array(); foreach ($columns as $column_id => $column_title) { + $rules[] = new Validators\Integer('task_limit['.$column_id.']', t('This value must be an integer')); + $rules[] = new Validators\GreaterThan('task_limit['.$column_id.']', t('This value must be greater than %d', 0), 0); $rules[] = new Validators\Required('title['.$column_id.']', t('The title is required')); $rules[] = new Validators\MaxLength('title['.$column_id.']', t('The maximum length is %d characters', 50), 50); } diff --git a/models/schema.php b/models/schema.php index e06271b3..4aa2a265 100644 --- a/models/schema.php +++ b/models/schema.php @@ -2,19 +2,24 @@ namespace Schema; +function version_6($pdo) +{ + $pdo->exec("ALTER TABLE columns ADD COLUMN task_limit INTEGER DEFAULT '0'"); +} + function version_5($pdo) { - $pdo->exec("ALTER TABLE tasks ADD column score INTEGER"); + $pdo->exec("ALTER TABLE tasks ADD COLUMN score INTEGER"); } function version_4($pdo) { - $pdo->exec("ALTER TABLE config ADD column timezone TEXT DEFAULT 'UTC'"); + $pdo->exec("ALTER TABLE config ADD COLUMN timezone TEXT DEFAULT 'UTC'"); } function version_3($pdo) { - $pdo->exec('ALTER TABLE projects ADD column token TEXT'); + $pdo->exec('ALTER TABLE projects ADD COLUMN token TEXT'); // For each existing project, assign a different token $rq = $pdo->prepare("SELECT id FROM projects WHERE token IS NULL"); @@ -32,7 +37,7 @@ function version_3($pdo) function version_2($pdo) { - $pdo->exec('ALTER TABLE tasks ADD column date_completed INTEGER'); + $pdo->exec('ALTER TABLE tasks ADD COLUMN date_completed INTEGER'); $pdo->exec('UPDATE tasks SET date_completed=date_creation WHERE is_active=0'); } diff --git a/templates/board_edit.php b/templates/board_edit.php index 605773ae..800e1c1d 100644 --- a/templates/board_edit.php +++ b/templates/board_edit.php @@ -12,9 +12,10 @@ <?php $i = 0; ?> - <?php foreach ($columns as $column_id => $column_title): ?> - <?= Helper\form_label(t('Column %d', ++$i), 'title['.$column_id.']') ?> - <?= Helper\form_text('title['.$column_id.']', $values, $errors, array('required')) ?> + <?php foreach ($columns as $column): ?> + <?= Helper\form_label(t('Column %d', ++$i), 'title['.$column['id'].']') ?> + <?= Helper\form_text('title['.$column['id'].']', $values, $errors, array('required')) ?> + <?= Helper\form_number('task_limit['.$column['id'].']', $values, $errors, array('placeholder="'.t('limit').'"')) ?> <a href="?controller=board&action=confirm&project_id=<?= $project['id'] ?>&column_id=<?= $column_id ?>"><?= t('Remove') ?></a> <?php endforeach ?> diff --git a/templates/board_index.php b/templates/board_index.php index 7a3f8ec1..aa581680 100644 --- a/templates/board_index.php +++ b/templates/board_index.php @@ -32,12 +32,26 @@ <th width="<?= $column_with ?>%"> <a href="?controller=task&action=create&project_id=<?= $column['project_id'] ?>&column_id=<?= $column['id'] ?>" title="<?= t('Add a new task') ?>">+</a> <?= Helper\escape($column['title']) ?> + <?php if ($column['task_limit']): ?> + <span title="<?= t('Task limit') ?>" class="task-limit"> + ( + <span id="task-number-column-<?= $column['id'] ?>"><?= count($column['tasks']) ?></span> + / + <?= Helper\escape($column['task_limit']) ?> + ) + </span> + <?php endif ?> </th> <?php endforeach ?> </tr> <tr> <?php foreach ($columns as $column): ?> - <td id="column-<?= $column['id'] ?>" class="column" data-column-id="<?= $column['id'] ?>" dropzone="copy"> + <td + id="column-<?= $column['id'] ?>" + class="column <?= $column['task_limit'] && count($column['tasks']) > $column['task_limit'] ? 'task-limit-warning' : '' ?>" + data-column-id="<?= $column['id'] ?>" + data-task-limit="<?= $column['task_limit'] ?>" + dropzone="copy"> <?php foreach ($column['tasks'] as $task): ?> <div class="draggable-item" draggable="true"> <div class="task task-<?= $task['color_id'] ?>" data-task-id="<?= $task['id'] ?>"> diff --git a/templates/board_public.php b/templates/board_public.php index 16c69ce2..339c8035 100644 --- a/templates/board_public.php +++ b/templates/board_public.php @@ -9,12 +9,15 @@ <?php foreach ($columns as $column): ?> <th width="<?= $column_with ?>%"> <?= Helper\escape($column['title']) ?> + <?php if ($column['task_limit']): ?> + <span title="<?= t('Task limit') ?>" class="task-limit">(<?= Helper\escape(count($column['tasks']).'/'.$column['task_limit']) ?>)</span> + <?php endif ?> </th> <?php endforeach ?> </tr> <tr> <?php foreach ($columns as $column): ?> - <td class="column"> + <td class="column <?= $column['task_limit'] && count($column['tasks']) > $column['task_limit'] ? 'task-limit-warning' : '' ?>"> <?php foreach ($column['tasks'] as $task): ?> <div class="draggable-item"> <div class="task task-<?= $task['color_id'] ?>"> diff --git a/vendor/SimpleValidator/Validators/GreaterThan.php b/vendor/SimpleValidator/Validators/GreaterThan.php new file mode 100644 index 00000000..e038cb61 --- /dev/null +++ b/vendor/SimpleValidator/Validators/GreaterThan.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +class GreaterThan extends Base +{ + private $min; + + + public function __construct($field, $error_message, $min) + { + parent::__construct($field, $error_message); + $this->min = $min; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + return $data[$this->field] > $this->min; + } + + return true; + } +}
\ No newline at end of file |