Add configurable task priority

This commit is contained in:
Frederic Guillot 2016-01-24 20:38:39 -05:00
parent 60f3d7f83d
commit 051bf1c9db
49 changed files with 401 additions and 19 deletions

View File

@ -4,6 +4,7 @@ Version 1.0.25 (unreleased)
New features:
* Add project owner (Directly Responsible Individual)
* Add configurable task priority
Version 1.0.24
--------------

View File

@ -40,6 +40,16 @@ class ProjectEdit extends Base
$this->renderView('project_edit/description', $values, $errors);
}
/**
* Change task priority
*
* @access public
*/
public function priority(array $values = array(), array $errors = array())
{
$this->renderView('project_edit/task_priority', $values, $errors);
}
/**
* Validate and update a project
*

View File

@ -32,6 +32,7 @@ class Taskcreation extends Base
}
$this->response->html($this->template->$method('task_creation/form', array(
'project' => $project,
'ajax' => $this->request->isAjax(),
'errors' => $errors,
'values' => $values + array('project_id' => $project['id']),

View File

@ -98,6 +98,7 @@ class Taskmodification extends Base
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
$project = $this->project->getById($task['project_id']);
$ajax = $this->request->isAjax();
if (empty($values)) {
@ -107,6 +108,7 @@ class Taskmodification extends Base
$this->dateParser->format($values, array('date_due'));
$params = array(
'project' => $project,
'values' => $values,
'errors' => $errors,
'task' => $task,

View File

@ -2,13 +2,15 @@
namespace Kanboard\Helper;
use Kanboard\Core\Base;
/**
* Task helpers
*
* @package helper
* @author Frederic Guillot
*/
class Task extends \Kanboard\Core\Base
class Task extends Base
{
public function getColors()
{
@ -34,4 +36,33 @@ class Task extends \Kanboard\Core\Base
{
return $this->taskPermission->canRemoveTask($task);
}
public function selectPriority(array $project, array $values)
{
$html = '';
if ($project['priority_end'] > $project['priority_start']) {
$range = range($project['priority_start'], $project['priority_end']);
$options = array_combine($range, $range);
$values += array('priority' => $project['priority_default']);
$html .= $this->helper->form->label(t('Priority'), 'priority');
$html .= $this->helper->form->select('priority', $options, $values, array(), array('tabindex="7"'));
}
return $html;
}
public function formatPriority(array $project, array $task)
{
$html = '';
if ($project['priority_end'] > $project['priority_start']) {
$html .= '<span class="task-board-priority" title="'.t('Task priority').'">';
$html .= $task['priority'] >= 0 ? 'P'.$task['priority'] : '-P'.abs($task['priority']);
$html .= '</span>';
}
return $html;
}
}

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1112,4 +1112,13 @@ return array(
'Those dates are useful for the project Gantt chart.' => 'Ces dates sont utiles pour le diagramme de Gantt des projets.',
'Private projects do not have users and groups management.' => 'Les projets privés n\'ont pas de gestion d\'utilisateurs et de groupes.',
'There is no project member.' => 'Il y a aucun membre du projet.',
'Priority' => 'Priorité',
'Task priority' => 'Priorité des tâches',
'General' => 'Général',
'Dates' => 'Dates',
'Default priority' => 'Priorité par défaut',
'Lowest priority' => 'Priorité basse',
'Highest priority' => 'Priorité haute',
'If you put zero to the low and high priority, this feature will be disabled.' => 'Si vous mettez zéro pour la priorité basse et haute, cette fonctionnalité sera désactivée.',
'Priority: %d' => 'Priorité : %d',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -1109,4 +1109,13 @@ return array(
// 'Those dates are useful for the project Gantt chart.' => '',
// 'Private projects do not have users and groups management.' => '',
// 'There is no project member.' => '',
// 'Priority' => '',
// 'Task priority' => '',
// 'General' => '',
// 'Dates' => '',
// 'Default priority' => '',
// 'Lowest priority' => '',
// 'Highest priority' => '',
// 'If you put zero to the low and high priority, this feature will be disabled.' => '',
// 'Priority: %d' => '',
);

View File

@ -334,6 +334,8 @@ class Project extends Base
$values['identifier'] = strtoupper($values['identifier']);
}
$this->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end'));
if (! $this->db->table(self::TABLE)->save($values)) {
$this->db->cancelTransaction();
return false;
@ -400,6 +402,8 @@ class Project extends Base
$values['identifier'] = strtoupper($values['identifier']);
}
$this->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end'));
return $this->exists($values['id']) &&
$this->db->table(self::TABLE)->eq('id', $values['id'])->save($values);
}

View File

@ -113,6 +113,7 @@ class TaskFinder extends Base
'tasks.is_active',
'tasks.score',
'tasks.category_id',
'tasks.priority',
'tasks.date_moved',
'tasks.recurrence_status',
'tasks.recurrence_trigger',
@ -308,6 +309,7 @@ class TaskFinder extends Base
tasks.is_active,
tasks.score,
tasks.category_id,
tasks.priority,
tasks.swimlane_id,
tasks.date_moved,
tasks.recurrence_status,

View File

@ -88,7 +88,7 @@ class TaskModification extends Base
$this->dateParser->convert($values, array('date_started'), true);
$this->removeFields($values, array('another_task', 'id'));
$this->resetFields($values, array('date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent'));
$this->convertIntegerFields($values, array('is_active', 'recurrence_status', 'recurrence_trigger', 'recurrence_factor', 'recurrence_timeframe', 'recurrence_basedate'));
$this->convertIntegerFields($values, array('priority', 'is_active', 'recurrence_status', 'recurrence_trigger', 'recurrence_factor', 'recurrence_timeframe', 'recurrence_basedate'));
$values['date_modification'] = time();
}

View File

@ -6,7 +6,15 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
const VERSION = 102;
const VERSION = 103;
function version_103(PDO $pdo)
{
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_default INT DEFAULT 0");
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_start INT DEFAULT 0");
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_end INT DEFAULT 3");
$pdo->exec("ALTER TABLE tasks ADD COLUMN priority INT DEFAULT 0");
}
function version_102(PDO $pdo)
{

View File

@ -6,7 +6,15 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
const VERSION = 82;
const VERSION = 83;
function version_83(PDO $pdo)
{
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_default INTEGER DEFAULT 0");
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_start INTEGER DEFAULT 0");
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_end INTEGER DEFAULT 3");
$pdo->exec("ALTER TABLE tasks ADD COLUMN priority INTEGER DEFAULT 0");
}
function version_82(PDO $pdo)
{

View File

@ -6,7 +6,15 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
use PDO;
const VERSION = 94;
const VERSION = 95;
function version_95(PDO $pdo)
{
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_default INTEGER DEFAULT 0");
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_start INTEGER DEFAULT 0");
$pdo->exec("ALTER TABLE projects ADD COLUMN priority_end INTEGER DEFAULT 3");
$pdo->exec("ALTER TABLE tasks ADD COLUMN priority INTEGER DEFAULT 0");
}
function version_94(PDO $pdo)
{

View File

@ -64,6 +64,7 @@ class RouteProvider implements ServiceProviderInterface
$container['route']->addRoute('project/:project_id/edit', 'ProjectEdit', 'edit');
$container['route']->addRoute('project/:project_id/edit/dates', 'ProjectEdit', 'dates');
$container['route']->addRoute('project/:project_id/edit/description', 'ProjectEdit', 'description');
$container['route']->addRoute('project/:project_id/edit/priority', 'ProjectEdit', 'priority');
// ProjectUser routes
$container['route']->addRoute('projects/managers/:user_id', 'projectuser', 'managers');

View File

@ -69,4 +69,6 @@
<i class="fa fa-flag flag-milestone"></i>
</span>
<?php endif ?>
<?= $this->task->formatPriority($project, $task) ?>
</div>

View File

@ -78,6 +78,7 @@
<?= $this->render('board/task_footer', array(
'task' => $task,
'not_editable' => $not_editable,
'project' => $project,
)) ?>
</div>
<?php endif ?>

View File

@ -25,5 +25,6 @@
<?= $this->render('board/task_footer', array(
'task' => $task,
'not_editable' => $not_editable,
'project' => $project,
)) ?>
</div>

View File

@ -4,6 +4,7 @@
<li ><?= $this->url->link(t('General'), 'ProjectEdit', 'edit', array('project_id' => $project['id'])) ?></li>
<li class="active"><?= $this->url->link(t('Dates'), 'ProjectEdit', 'dates', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Description'), 'ProjectEdit', 'description', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Task priority'), 'ProjectEdit', 'priority', array('project_id' => $project['id'])) ?></li>
</ul>
</div>
<form method="post" action="<?= $this->url->href('ProjectEdit', 'update', array('project_id' => $project['id'], 'redirect' => 'dates')) ?>" autocomplete="off">

View File

@ -4,6 +4,7 @@
<li><?= $this->url->link(t('General'), 'ProjectEdit', 'edit', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Dates'), 'ProjectEdit', 'dates', array('project_id' => $project['id'])) ?></li>
<li class="active"><?= $this->url->link(t('Description'), 'ProjectEdit', 'description', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Task priority'), 'ProjectEdit', 'priority', array('project_id' => $project['id'])) ?></li>
</ul>
</div>
<form method="post" action="<?= $this->url->href('ProjectEdit', 'update', array('project_id' => $project['id'], 'redirect' => 'description')) ?>" autocomplete="off">

View File

@ -4,6 +4,7 @@
<li class="active"><?= $this->url->link(t('General'), 'ProjectEdit', 'edit', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Dates'), 'ProjectEdit', 'dates', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Description'), 'ProjectEdit', 'description', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Task priority'), 'ProjectEdit', 'priority', array('project_id' => $project['id'])) ?></li>
</ul>
</div>
<form method="post" action="<?= $this->url->href('ProjectEdit', 'update', array('project_id' => $project['id'], 'redirect' => 'edit')) ?>" autocomplete="off">

View File

@ -0,0 +1,29 @@
<div class="page-header">
<h2><?= t('Edit project') ?></h2>
<ul>
<li ><?= $this->url->link(t('General'), 'ProjectEdit', 'edit', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Dates'), 'ProjectEdit', 'dates', array('project_id' => $project['id'])) ?></li>
<li><?= $this->url->link(t('Description'), 'ProjectEdit', 'description', array('project_id' => $project['id'])) ?></li>
<li class="active"><?= $this->url->link(t('Task priority'), 'ProjectEdit', 'priority', array('project_id' => $project['id'])) ?></li>
</ul>
</div>
<form method="post" action="<?= $this->url->href('ProjectEdit', 'update', array('project_id' => $project['id'], 'redirect' => 'priority')) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->hidden('name', $values) ?>
<?= $this->form->label(t('Default priority'), 'priority_default') ?>
<?= $this->form->number('priority_default', $values, $errors) ?>
<?= $this->form->label(t('Lowest priority'), 'priority_start') ?>
<?= $this->form->number('priority_start', $values, $errors) ?>
<?= $this->form->label(t('Highest priority'), 'priority_end') ?>
<?= $this->form->number('priority_end', $values, $errors) ?>
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
</div>
</form>
<p class="alert alert-info"><?= t('If you put zero to the low and high priority, this feature will be disabled.') ?></p>

View File

@ -4,6 +4,9 @@
<span class="task-score"><?= $this->e($task['score']) ?></span>
<?php endif ?>
<ul>
<li>
<strong><?= t('Priority: %d', $task['priority']) ?></strong>
</li>
<?php if ($task['reference']): ?>
<li>
<strong><?= t('Reference: %s', $task['reference']) ?></strong>

View File

@ -16,7 +16,7 @@
<div class="form-column">
<?= $this->form->label(t('Title'), 'title') ?>
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large') ?><br/>
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large') ?>
<?= $this->form->label(t('Description'), 'description') ?>
@ -57,32 +57,34 @@
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Assignee'), 'owner_id') ?>
<?= $this->form->select('owner_id', $users_list, $values, $errors, array('tabindex="3"')) ?><br/>
<?= $this->form->select('owner_id', $users_list, $values, $errors, array('tabindex="3"')) ?>
<?= $this->form->label(t('Category'), 'category_id') ?>
<?= $this->form->select('category_id', $categories_list, $values, $errors, array('tabindex="4"')) ?><br/>
<?= $this->form->select('category_id', $categories_list, $values, $errors, array('tabindex="4"')) ?>
<?php if (! (count($swimlanes_list) === 1 && key($swimlanes_list) === 0)): ?>
<?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
<?= $this->form->select('swimlane_id', $swimlanes_list, $values, $errors, array('tabindex="5"')) ?><br/>
<?= $this->form->select('swimlane_id', $swimlanes_list, $values, $errors, array('tabindex="5"')) ?>
<?php endif ?>
<?= $this->form->label(t('Column'), 'column_id') ?>
<?= $this->form->select('column_id', $columns_list, $values, $errors, array('tabindex="6"')) ?><br/>
<?= $this->form->select('column_id', $columns_list, $values, $errors, array('tabindex="6"')) ?>
<?= $this->task->selectPriority($project, $values) ?>
<?= $this->form->label(t('Complexity'), 'score') ?>
<?= $this->form->number('score', $values, $errors, array('tabindex="8"')) ?><br/>
<?= $this->form->number('score', $values, $errors, array('tabindex="9"')) ?>
<?= $this->form->label(t('Original estimate'), 'time_estimated') ?>
<?= $this->form->numeric('time_estimated', $values, $errors, array('tabindex="9"')) ?> <?= t('hours') ?><br/>
<?= $this->form->numeric('time_estimated', $values, $errors, array('tabindex="10"')) ?> <?= t('hours') ?>
<?= $this->form->label(t('Due Date'), 'date_due') ?>
<?= $this->form->text('date_due', $values, $errors, array('placeholder="'.$this->text->in($date_format, $date_formats).'"', 'tabindex="10"'), 'form-date') ?><br/>
<?= $this->form->text('date_due', $values, $errors, array('placeholder="'.$this->text->in($date_format, $date_formats).'"', 'tabindex="11"'), 'form-date') ?>
<div class="form-help"><?= t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')) ?></div>
</div>
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue" tabindex="11"/>
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue" tabindex="12"/>
<?= t('or') ?> <?= $this->url->link(t('cancel'), 'board', 'show', array('project_id' => $values['project_id']), false, 'close-popover') ?>
</div>
</form>

View File

@ -8,7 +8,7 @@
<div class="form-column">
<?= $this->form->label(t('Title'), 'title') ?>
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"')) ?><br/>
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"')) ?>
<?= $this->form->label(t('Description'), 'description') ?>
<div class="form-tabs">
@ -45,16 +45,18 @@
<?= $this->form->hidden('project_id', $values) ?>
<?= $this->form->label(t('Assignee'), 'owner_id') ?>
<?= $this->form->select('owner_id', $users_list, $values, $errors, array('tabindex="3"')) ?><br/>
<?= $this->form->select('owner_id', $users_list, $values, $errors, array('tabindex="3"')) ?>
<?= $this->form->label(t('Category'), 'category_id') ?>
<?= $this->form->select('category_id', $categories_list, $values, $errors, array('tabindex="4"')) ?><br/>
<?= $this->form->select('category_id', $categories_list, $values, $errors, array('tabindex="4"')) ?>
<?= $this->form->label(t('Complexity'), 'score') ?>
<?= $this->form->number('score', $values, $errors, array('tabindex="6"')) ?><br/>
<?= $this->form->number('score', $values, $errors, array('tabindex="6"')) ?>
<?= $this->task->selectPriority($project, $values) ?>
<?= $this->form->label(t('Due Date'), 'date_due') ?>
<?= $this->form->text('date_due', $values, $errors, array('placeholder="'.$this->text->in($date_format, $date_formats).'"', 'tabindex="7"'), 'form-date') ?><br/>
<?= $this->form->text('date_due', $values, $errors, array('placeholder="'.$this->text->in($date_format, $date_formats).'"', 'tabindex="8"'), 'form-date') ?>
<div class="form-help"><?= t('Others formats accepted: %s and %s', date('Y-m-d'), date('Y_m_d')) ?></div>
</div>

View File

@ -24,6 +24,9 @@ class ProjectValidator extends Base
{
return array(
new Validators\Integer('id', t('This value must be an integer')),
new Validators\Integer('priority_default', t('This value must be an integer')),
new Validators\Integer('priority_start', t('This value must be an integer')),
new Validators\Integer('priority_end', t('This value must be an integer')),
new Validators\Integer('is_active', t('This value must be an integer')),
new Validators\Required('name', t('The project name is required')),
new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50),

View File

@ -37,6 +37,7 @@ class TaskValidator extends Base
new Validators\Integer('recurrence_basedate', t('This value must be an integer')),
new Validators\Integer('recurrence_trigger', t('This value must be an integer')),
new Validators\Integer('recurrence_status', t('This value must be an integer')),
new Validators\Integer('priority', t('This value must be an integer')),
new Validators\MaxLength('title', t('The maximum length is %d characters', 200), 200),
new Validators\MaxLength('reference', t('The maximum length is %d characters', 50), 50),
new Validators\Date('date_due', t('Invalid date'), $this->dateParser->getDateFormats()),

View File

@ -0,0 +1,32 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Helper\Task;
class TaskHelperTest extends Base
{
public function testSelectPriority()
{
$helper = new Task($this->container);
$this->assertNotEmpty($helper->selectPriority(array('priority_end' => '3', 'priority_start' => '1', 'priority_default' => '2'), array()));
$this->assertEmpty($helper->selectPriority(array('priority_end' => '3', 'priority_start' => '3', 'priority_default' => '2'), array()));
}
public function testFormatPriority()
{
$helper = new Task($this->container);
$this->assertEquals(
'<span class="task-board-priority" title="Task priority">P2</span>',
$helper->formatPriority(array('priority_end' => '3', 'priority_start' => '1', 'priority_default' => '2'), array('priority' => 2))
);
$this->assertEquals(
'<span class="task-board-priority" title="Task priority">-P6</span>',
$helper->formatPriority(array('priority_end' => '3', 'priority_start' => '1', 'priority_default' => '2'), array('priority' => -6))
);
$this->assertEmpty($helper->formatPriority(array('priority_end' => '3', 'priority_start' => '3', 'priority_default' => '2'), array()));
}
}

View File

@ -305,4 +305,24 @@ class ProjectTest extends Base
$this->assertEquals('', $project['owner_username']);
$this->assertEquals(0, $project['owner_id']);
}
public function testPriority()
{
$projectModel = new Project($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'My project 2')));
$project = $projectModel->getById(1);
$this->assertNotEmpty($project);
$this->assertEquals(0, $project['priority_default']);
$this->assertEquals(0, $project['priority_start']);
$this->assertEquals(3, $project['priority_end']);
$this->assertTrue($projectModel->update(array('id' => 1, 'priority_start' => 2, 'priority_end' => 5, 'priority_default' => 4)));
$project = $projectModel->getById(1);
$this->assertNotEmpty($project);
$this->assertEquals(4, $project['priority_default']);
$this->assertEquals(2, $project['priority_start']);
$this->assertEquals(5, $project['priority_end']);
}
}