summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--app/Controller/ProjectEdit.php10
-rw-r--r--app/Controller/Taskcreation.php1
-rw-r--r--app/Controller/Taskmodification.php2
-rw-r--r--app/Helper/Task.php33
-rw-r--r--app/Locale/bs_BA/translations.php9
-rw-r--r--app/Locale/cs_CZ/translations.php9
-rw-r--r--app/Locale/da_DK/translations.php9
-rw-r--r--app/Locale/de_DE/translations.php9
-rw-r--r--app/Locale/es_ES/translations.php9
-rw-r--r--app/Locale/fi_FI/translations.php9
-rw-r--r--app/Locale/fr_FR/translations.php9
-rw-r--r--app/Locale/hu_HU/translations.php9
-rw-r--r--app/Locale/id_ID/translations.php9
-rw-r--r--app/Locale/it_IT/translations.php9
-rw-r--r--app/Locale/ja_JP/translations.php9
-rw-r--r--app/Locale/my_MY/translations.php9
-rw-r--r--app/Locale/nb_NO/translations.php9
-rw-r--r--app/Locale/nl_NL/translations.php9
-rw-r--r--app/Locale/pl_PL/translations.php9
-rw-r--r--app/Locale/pt_BR/translations.php9
-rw-r--r--app/Locale/pt_PT/translations.php9
-rw-r--r--app/Locale/ru_RU/translations.php9
-rw-r--r--app/Locale/sr_Latn_RS/translations.php9
-rw-r--r--app/Locale/sv_SE/translations.php9
-rw-r--r--app/Locale/th_TH/translations.php9
-rw-r--r--app/Locale/tr_TR/translations.php9
-rw-r--r--app/Locale/zh_CN/translations.php9
-rw-r--r--app/Model/Project.php4
-rw-r--r--app/Model/TaskFinder.php2
-rw-r--r--app/Model/TaskModification.php2
-rw-r--r--app/Schema/Mysql.php10
-rw-r--r--app/Schema/Postgres.php10
-rw-r--r--app/Schema/Sqlite.php10
-rw-r--r--app/ServiceProvider/RouteProvider.php1
-rw-r--r--app/Template/board/task_footer.php2
-rw-r--r--app/Template/board/task_private.php1
-rw-r--r--app/Template/board/task_public.php1
-rw-r--r--app/Template/project_edit/dates.php1
-rw-r--r--app/Template/project_edit/description.php1
-rw-r--r--app/Template/project_edit/general.php1
-rw-r--r--app/Template/project_edit/task_priority.php29
-rw-r--r--app/Template/task/details.php3
-rw-r--r--app/Template/task_creation/form.php20
-rw-r--r--app/Template/task_modification/edit_task.php12
-rw-r--r--app/Validator/ProjectValidator.php3
-rw-r--r--app/Validator/TaskValidator.php1
-rw-r--r--tests/units/Helper/TaskHelperTest.php32
-rw-r--r--tests/units/Model/ProjectTest.php20
49 files changed, 401 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c46bb00..ec5f36b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
--------------
diff --git a/app/Controller/ProjectEdit.php b/app/Controller/ProjectEdit.php
index 3b0a3da3..0dfc7de3 100644
--- a/app/Controller/ProjectEdit.php
+++ b/app/Controller/ProjectEdit.php
@@ -41,6 +41,16 @@ class ProjectEdit extends Base
}
/**
+ * 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
*
* @access public
diff --git a/app/Controller/Taskcreation.php b/app/Controller/Taskcreation.php
index 4d74fac6..49ccea7f 100644
--- a/app/Controller/Taskcreation.php
+++ b/app/Controller/Taskcreation.php
@@ -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']),
diff --git a/app/Controller/Taskmodification.php b/app/Controller/Taskmodification.php
index 81cf430f..2c97970b 100644
--- a/app/Controller/Taskmodification.php
+++ b/app/Controller/Taskmodification.php
@@ -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,
diff --git a/app/Helper/Task.php b/app/Helper/Task.php
index 1405a167..500b8a89 100644
--- a/app/Helper/Task.php
+++ b/app/Helper/Task.php
@@ -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;
+ }
}
diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php
index e1af1c08..90ab1296 100644
--- a/app/Locale/bs_BA/translations.php
+++ b/app/Locale/bs_BA/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index b93b7c23..83d88f35 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 63850d70..7a82bc1e 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index ef056972..1158dd67 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 91709476..16c96ec5 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index c887e02d..cde825e2 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index f36ce104..32110e1c 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -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',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index e12a7aad..25d55bb2 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index 49d61d58..e3316405 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index 5e2c32a9..1e32213f 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index f1884b93..b9cde718 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php
index 65aaa4e3..43c288c7 100644
--- a/app/Locale/my_MY/translations.php
+++ b/app/Locale/my_MY/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index 520149d5..682f44a8 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 87f5323e..4f38f256 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 37dcfe3d..ee0ceb47 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index 6e47c514..09e87048 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index f57657ee..19c2ebf7 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 02bf9934..d09258ed 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index c779cd6c..2b3553c2 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index ca412273..1c01e94d 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index b2b9a55b..e0de5844 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index 17163f45..c4da560d 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -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' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index e4b732ef..e0b90b58 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -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' => '',
);
diff --git a/app/Model/Project.php b/app/Model/Project.php
index ba0716b0..d0a8bfc8 100644
--- a/app/Model/Project.php
+++ b/app/Model/Project.php
@@ -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);
}
diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php
index 836fbe46..1c83136b 100644
--- a/app/Model/TaskFinder.php
+++ b/app/Model/TaskFinder.php
@@ -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,
diff --git a/app/Model/TaskModification.php b/app/Model/TaskModification.php
index a0ad292c..eee7b2e0 100644
--- a/app/Model/TaskModification.php
+++ b/app/Model/TaskModification.php
@@ -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();
}
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index ad7f7be1..8f1db510 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -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)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index d23a7723..a7bf8054 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -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)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index daa70f54..08689749 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -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)
{
diff --git a/app/ServiceProvider/RouteProvider.php b/app/ServiceProvider/RouteProvider.php
index 5a5c8652..057a1b3c 100644
--- a/app/ServiceProvider/RouteProvider.php
+++ b/app/ServiceProvider/RouteProvider.php
@@ -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');
diff --git a/app/Template/board/task_footer.php b/app/Template/board/task_footer.php
index 4a16364c..26f3b1d4 100644
--- a/app/Template/board/task_footer.php
+++ b/app/Template/board/task_footer.php
@@ -69,4 +69,6 @@
<i class="fa fa-flag flag-milestone"></i>
</span>
<?php endif ?>
+
+ <?= $this->task->formatPriority($project, $task) ?>
</div>
diff --git a/app/Template/board/task_private.php b/app/Template/board/task_private.php
index 8d76453c..4880af00 100644
--- a/app/Template/board/task_private.php
+++ b/app/Template/board/task_private.php
@@ -78,6 +78,7 @@
<?= $this->render('board/task_footer', array(
'task' => $task,
'not_editable' => $not_editable,
+ 'project' => $project,
)) ?>
</div>
<?php endif ?>
diff --git a/app/Template/board/task_public.php b/app/Template/board/task_public.php
index bacdcef4..d02722bb 100644
--- a/app/Template/board/task_public.php
+++ b/app/Template/board/task_public.php
@@ -25,5 +25,6 @@
<?= $this->render('board/task_footer', array(
'task' => $task,
'not_editable' => $not_editable,
+ 'project' => $project,
)) ?>
</div> \ No newline at end of file
diff --git a/app/Template/project_edit/dates.php b/app/Template/project_edit/dates.php
index d3f4bad8..cb585c6a 100644
--- a/app/Template/project_edit/dates.php
+++ b/app/Template/project_edit/dates.php
@@ -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">
diff --git a/app/Template/project_edit/description.php b/app/Template/project_edit/description.php
index 3af484d5..dce8ab10 100644
--- a/app/Template/project_edit/description.php
+++ b/app/Template/project_edit/description.php
@@ -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">
diff --git a/app/Template/project_edit/general.php b/app/Template/project_edit/general.php
index 1da913da..5caefa2d 100644
--- a/app/Template/project_edit/general.php
+++ b/app/Template/project_edit/general.php
@@ -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">
diff --git a/app/Template/project_edit/task_priority.php b/app/Template/project_edit/task_priority.php
new file mode 100644
index 00000000..e54215b2
--- /dev/null
+++ b/app/Template/project_edit/task_priority.php
@@ -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>
diff --git a/app/Template/task/details.php b/app/Template/task/details.php
index 74799b15..d885ca9c 100644
--- a/app/Template/task/details.php
+++ b/app/Template/task/details.php
@@ -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>
diff --git a/app/Template/task_creation/form.php b/app/Template/task_creation/form.php
index c9f367a0..eaf9024d 100644
--- a/app/Template/task_creation/form.php
+++ b/app/Template/task_creation/form.php
@@ -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> \ No newline at end of file
diff --git a/app/Template/task_modification/edit_task.php b/app/Template/task_modification/edit_task.php
index 6fdb77b5..2701dd8f 100644
--- a/app/Template/task_modification/edit_task.php
+++ b/app/Template/task_modification/edit_task.php
@@ -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>
diff --git a/app/Validator/ProjectValidator.php b/app/Validator/ProjectValidator.php
index 53cb7a37..1c6c90f8 100644
--- a/app/Validator/ProjectValidator.php
+++ b/app/Validator/ProjectValidator.php
@@ -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),
diff --git a/app/Validator/TaskValidator.php b/app/Validator/TaskValidator.php
index c18a9761..7b73aeba 100644
--- a/app/Validator/TaskValidator.php
+++ b/app/Validator/TaskValidator.php
@@ -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()),
diff --git a/tests/units/Helper/TaskHelperTest.php b/tests/units/Helper/TaskHelperTest.php
new file mode 100644
index 00000000..726188e4
--- /dev/null
+++ b/tests/units/Helper/TaskHelperTest.php
@@ -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()));
+ }
+}
diff --git a/tests/units/Model/ProjectTest.php b/tests/units/Model/ProjectTest.php
index afd047b0..cadb42a6 100644
--- a/tests/units/Model/ProjectTest.php
+++ b/tests/units/Model/ProjectTest.php
@@ -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']);
+ }
}