summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Controller/ProjectListController.php15
-rw-r--r--app/Controller/TaskListController.php2
-rw-r--r--app/Locale/bs_BA/translations.php11
-rw-r--r--app/Locale/cs_CZ/translations.php11
-rw-r--r--app/Locale/da_DK/translations.php11
-rw-r--r--app/Locale/de_DE/translations.php11
-rw-r--r--app/Locale/el_GR/translations.php11
-rw-r--r--app/Locale/es_ES/translations.php11
-rw-r--r--app/Locale/fi_FI/translations.php11
-rw-r--r--app/Locale/fr_FR/translations.php11
-rw-r--r--app/Locale/hu_HU/translations.php11
-rw-r--r--app/Locale/id_ID/translations.php11
-rw-r--r--app/Locale/it_IT/translations.php11
-rw-r--r--app/Locale/ja_JP/translations.php11
-rw-r--r--app/Locale/ko_KR/translations.php11
-rw-r--r--app/Locale/my_MY/translations.php11
-rw-r--r--app/Locale/nb_NO/translations.php11
-rw-r--r--app/Locale/nl_NL/translations.php11
-rw-r--r--app/Locale/pl_PL/translations.php11
-rw-r--r--app/Locale/pt_BR/translations.php11
-rw-r--r--app/Locale/pt_PT/translations.php11
-rw-r--r--app/Locale/ru_RU/translations.php11
-rw-r--r--app/Locale/sr_Latn_RS/translations.php11
-rw-r--r--app/Locale/sv_SE/translations.php11
-rw-r--r--app/Locale/th_TH/translations.php11
-rw-r--r--app/Locale/tr_TR/translations.php11
-rw-r--r--app/Locale/zh_CN/translations.php11
-rw-r--r--app/Model/ColorModel.php3
-rw-r--r--app/Model/ProjectModel.php20
-rw-r--r--app/Template/board/task_footer.php12
-rw-r--r--app/Template/board/task_private.php3
-rw-r--r--app/Template/project_list/header.php12
-rw-r--r--app/Template/project_list/listing.php47
-rw-r--r--app/Template/project_list/project_details.php15
-rw-r--r--app/Template/project_list/project_title.php33
-rw-r--r--app/Template/project_list/show.php101
-rw-r--r--app/Template/project_list/sort_menu.php26
-rw-r--r--app/Template/task_list/header.php12
-rw-r--r--app/Template/task_list/listing.php33
-rw-r--r--app/Template/task_list/show.php66
-rw-r--r--app/Template/task_list/sort_menu.php32
-rw-r--r--app/Template/task_list/task_avatars.php20
-rw-r--r--app/Template/task_list/task_details.php23
-rw-r--r--app/Template/task_list/task_icons.php94
-rw-r--r--app/Template/task_list/task_title.php11
45 files changed, 669 insertions, 186 deletions
diff --git a/app/Controller/ProjectListController.php b/app/Controller/ProjectListController.php
index 4de73c97..95ff5d91 100644
--- a/app/Controller/ProjectListController.php
+++ b/app/Controller/ProjectListController.php
@@ -18,24 +18,21 @@ class ProjectListController extends BaseController
public function show()
{
if ($this->userSession->isAdmin()) {
- $project_ids = $this->projectModel->getAllIds();
+ $projectIds = $this->projectModel->getAllIds();
} else {
- $project_ids = $this->projectPermissionModel->getProjectIds($this->userSession->getId());
+ $projectIds = $this->projectPermissionModel->getProjectIds($this->userSession->getId());
}
- $nb_projects = count($project_ids);
-
$paginator = $this->paginator
->setUrl('ProjectListController', 'show')
->setMax(20)
->setOrder('name')
- ->setQuery($this->projectModel->getQueryColumnStats($project_ids))
+ ->setQuery($this->projectModel->getQueryByProjectIds($projectIds))
->calculate();
- $this->response->html($this->helper->layout->app('project_list/show', array(
- 'paginator' => $paginator,
- 'nb_projects' => $nb_projects,
- 'title' => t('Projects').' ('.$nb_projects.')'
+ $this->response->html($this->helper->layout->app('project_list/listing', array(
+ 'paginator' => $paginator,
+ 'title' => t('Projects') . ' (' . $paginator->getTotal() . ')',
)));
}
}
diff --git a/app/Controller/TaskListController.php b/app/Controller/TaskListController.php
index c6d1fa92..3f48be85 100644
--- a/app/Controller/TaskListController.php
+++ b/app/Controller/TaskListController.php
@@ -35,7 +35,7 @@ class TaskListController extends BaseController
)
->calculate();
- $this->response->html($this->helper->layout->app('task_list/show', array(
+ $this->response->html($this->helper->layout->app('task_list/listing', array(
'project' => $project,
'title' => $project['name'],
'description' => $this->helper->projectHeader->getDescription($project),
diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php
index 3da046d9..8c9f2cef 100644
--- a/app/Locale/bs_BA/translations.php
+++ b/app/Locale/bs_BA/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index 46427df9..71f11ba4 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 9d4d6a87..b5147755 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 355607df..95b45ef2 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -1321,4 +1321,15 @@ return array(
'Your project must have at least one active swimlane.' => 'Ihr Projekt muss mindestens eine aktive Swimlane haben.',
'Project: %s' => 'Projekt: %s',
'Automatic action not found: "%s"' => 'Automatische Aktion nicht gefunden: "%s"',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php
index d58d375e..4d4bbc95 100644
--- a/app/Locale/el_GR/translations.php
+++ b/app/Locale/el_GR/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index cd65f3be..10cb41e6 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index c8345a2d..397f8133 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index cf538fc9..3016a18d 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -1321,4 +1321,15 @@ return array(
'Your project must have at least one active swimlane.' => 'Votre projet doit avoir au moins une swimlane active.',
'Project: %s' => 'Projet : %s',
'Automatic action not found: "%s"' => 'Action automatique introuvable : « %s »',
+ '%d projects' => '%d projets',
+ '%d project' => '%d projet',
+ 'There is no project.' => 'Il n\'y a pas de projet.',
+ 'Sort' => 'Trier',
+ 'Project ID' => 'ID du projet',
+ 'Project name' => 'Nom du projet',
+ 'Public' => 'Public',
+ 'Private' => 'Privé',
+ '%d tasks' => '%d tâches',
+ '%d task' => '%d tâche',
+ 'Task ID' => 'ID de la tâche',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index a555c01e..aa50dc0e 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index 84fda7ce..e12e0468 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index f469748c..49ab2a7f 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 7523986f..102806a7 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php
index 8b37183c..8322de3d 100644
--- a/app/Locale/ko_KR/translations.php
+++ b/app/Locale/ko_KR/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php
index 5878ac18..73a25ca7 100644
--- a/app/Locale/my_MY/translations.php
+++ b/app/Locale/my_MY/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index dba51b02..bfe996bc 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 5fb19d35..bc6f81d2 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index b3e02555..cb60ec5b 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index b7a33138..0e8afdaf 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index a50c9204..7aa39b2e 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index bef9dbc3..ebb34ab4 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 8b38e584..76d321f3 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 60af921c..b662bf32 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index e9647129..e47f677a 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index 1b00621a..61763533 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index a513dccd..0ae0ca53 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -1321,4 +1321,15 @@ return array(
// 'Your project must have at least one active swimlane.' => '',
// 'Project: %s' => '',
// 'Automatic action not found: "%s"' => '',
+ // '%d projects' => '',
+ // '%d project' => '',
+ // 'There is no project.' => '',
+ // 'Sort' => '',
+ // 'Project ID' => '',
+ // 'Project name' => '',
+ // 'Public' => '',
+ // 'Private' => '',
+ // '%d tasks' => '',
+ // '%d task' => '',
+ // 'Task ID' => '',
);
diff --git a/app/Model/ColorModel.php b/app/Model/ColorModel.php
index 9fa7ff85..7e166124 100644
--- a/app/Model/ColorModel.php
+++ b/app/Model/ColorModel.php
@@ -218,11 +218,12 @@ class ColorModel extends Base
$buffer = '';
foreach ($this->default_colors as $color => $values) {
- $buffer .= 'div.color-'.$color.' {';
+ $buffer .= '.task-board.color-'.$color.', .task-summary-container.color-'.$color.', .color-picker-square.color-'.$color.' {';
$buffer .= 'background-color: '.$values['background'].';';
$buffer .= 'border-color: '.$values['border'];
$buffer .= '}';
$buffer .= 'td.color-'.$color.' { background-color: '.$values['background'].'}';
+ $buffer .= '.table-list-row.color-'.$color.' {border-left: 5px solid '.$values['border'].'}';
}
return $buffer;
diff --git a/app/Model/ProjectModel.php b/app/Model/ProjectModel.php
index b88a8c8b..aa7c002d 100644
--- a/app/Model/ProjectModel.php
+++ b/app/Model/ProjectModel.php
@@ -318,6 +318,26 @@ class ProjectModel extends Base
}
/**
+ * Get query for list of project without column statistics
+ *
+ * @access public
+ * @param array $projectIds
+ * @return \PicoDb\Table
+ */
+ public function getQueryByProjectIds(array $projectIds)
+ {
+ if (empty($projectIds)) {
+ return $this->db->table(ProjectModel::TABLE)->eq(ProjectModel::TABLE.'.id', 0);
+ }
+
+ return $this->db
+ ->table(ProjectModel::TABLE)
+ ->columns(self::TABLE.'.*', UserModel::TABLE.'.username AS owner_username', UserModel::TABLE.'.name AS owner_name')
+ ->join(UserModel::TABLE, 'id', 'owner_id')
+ ->in(self::TABLE.'.id', $projectIds);
+ }
+
+ /**
* Create a project
*
* @access public
diff --git a/app/Template/board/task_footer.php b/app/Template/board/task_footer.php
index 74c1b74d..79b7c3e9 100644
--- a/app/Template/board/task_footer.php
+++ b/app/Template/board/task_footer.php
@@ -57,11 +57,11 @@
<?php endif ?>
<?php if (! empty($task['date_due'])): ?>
- <span class="task-board-date
+ <span class="task-date
<?php if (date('Y-m-d') == date('Y-m-d', $task['date_due'])): ?>
- task-board-date-today
+ task-date-today
<?php elseif (time() > $task['date_due']): ?>
- task-board-date-overdue
+ task-date-overdue
<?php endif ?>
">
<i class="fa fa-calendar"></i>
@@ -117,9 +117,9 @@
<?php endif ?>
<?php if ($task['is_active'] == 1): ?>
- <div class="task-board-age">
- <span title="<?= t('Task age in days')?>" class="task-board-age-total"><?= $this->dt->age($task['date_creation']) ?></span>
- <span title="<?= t('Days in this column')?>" class="task-board-age-column"><?= $this->dt->age($task['date_moved']) ?></span>
+ <div class="task-icon-age">
+ <span title="<?= t('Task age in days')?>" class="task-icon-age-total"><?= $this->dt->age($task['date_creation']) ?></span>
+ <span title="<?= t('Days in this column')?>" class="task-icon-age-column"><?= $this->dt->age($task['date_moved']) ?></span>
</div>
<?php else: ?>
<span class="task-board-closed"><i class="fa fa-ban fa-fw"></i><?= t('Closed') ?></span>
diff --git a/app/Template/board/task_private.php b/app/Template/board/task_private.php
index 1be64fcf..c4afc0bf 100644
--- a/app/Template/board/task_private.php
+++ b/app/Template/board/task_private.php
@@ -32,6 +32,7 @@
</div>
<?php else: ?>
<div class="task-board-expanded">
+ <div class="task-board-saving-icon" style="display: none;"><i class="fa fa-spinner fa-pulse fa-2x"></i></div>
<div class="task-board-header">
<?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?>
<?= $this->render('task/dropdown', array('task' => $task)) ?>
@@ -54,8 +55,6 @@
</div>
<?= $this->hook->render('template:board:private:task:after-title', array('task' => $task)) ?>
- <div class="task-board-saving-icon" style="display: none;"><i class="fa fa-spinner fa-pulse fa-2x"></i></div>
-
<?= $this->render('board/task_footer', array(
'task' => $task,
'not_editable' => $not_editable,
diff --git a/app/Template/project_list/header.php b/app/Template/project_list/header.php
new file mode 100644
index 00000000..24ac9041
--- /dev/null
+++ b/app/Template/project_list/header.php
@@ -0,0 +1,12 @@
+<div class="table-list-header">
+ <div class="table-list-header-count">
+ <?php if ($paginator->getTotal() > 1): ?>
+ <?= t('%d projects', $paginator->getTotal()) ?>
+ <?php else: ?>
+ <?= t('%d project', $paginator->getTotal()) ?>
+ <?php endif ?>
+ </div>
+ <div class="table-list-header-menu">
+ <?= $this->render('project_list/sort_menu', array('paginator' => $paginator)) ?>
+ </div>
+</div>
diff --git a/app/Template/project_list/listing.php b/app/Template/project_list/listing.php
new file mode 100644
index 00000000..9c5dfe0e
--- /dev/null
+++ b/app/Template/project_list/listing.php
@@ -0,0 +1,47 @@
+<div class="page-header">
+ <ul>
+ <?= $this->hook->render('template:project-list:menu:before') ?>
+
+ <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
+ <li>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
+ </li>
+ <?php endif ?>
+
+ <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
+ <li>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
+ </li>
+ <?php endif ?>
+
+ <?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
+ <li><?= $this->url->icon('user', t('Users overview'), 'ProjectUserOverviewController', 'managers') ?></li>
+ <?php endif ?>
+
+ <?php if ($this->user->hasAccess('ProjectGanttController', 'show')): ?>
+ <li><?= $this->url->icon('sliders', t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?></li>
+ <?php endif ?>
+
+ <?= $this->hook->render('template:project-list:menu:after') ?>
+ </ul>
+</div>
+<?php if ($paginator->isEmpty()): ?>
+ <p class="alert"><?= t('There is no project.') ?></p>
+<?php else: ?>
+ <div class="table-list">
+ <?= $this->render('project_list/header', array('paginator' => $paginator)) ?>
+ <?php foreach ($paginator->getCollection() as $project): ?>
+ <div class="table-list-row table-border-left">
+ <?= $this->render('project_list/project_title', array(
+ 'project' => $project,
+ )) ?>
+
+ <?= $this->render('project_list/project_details', array(
+ 'project' => $project,
+ )) ?>
+ </div>
+ <?php endforeach ?>
+ </div>
+
+ <?= $paginator ?>
+<?php endif ?>
diff --git a/app/Template/project_list/project_details.php b/app/Template/project_list/project_details.php
new file mode 100644
index 00000000..136afc92
--- /dev/null
+++ b/app/Template/project_list/project_details.php
@@ -0,0 +1,15 @@
+<div class="table-list-details">
+ <ul>
+ <?php if ($project['owner_id'] > 0): ?>
+ <li><?= $this->text->e($project['owner_name'] ?: $project['owner_username']) ?></li>
+ <?php endif ?>
+
+ <?php if ($project['start_date']): ?>
+ <li><?= t('Start date:').' '.$this->dt->date($project['start_date']) ?></li>
+ <?php endif ?>
+
+ <?php if ($project['end_date']): ?>
+ <li><?= t('End date:').' '.$this->dt->date($project['end_date']) ?></li>
+ <?php endif ?>
+ </ul>
+</div> \ No newline at end of file
diff --git a/app/Template/project_list/project_title.php b/app/Template/project_list/project_title.php
new file mode 100644
index 00000000..ddec4131
--- /dev/null
+++ b/app/Template/project_list/project_title.php
@@ -0,0 +1,33 @@
+<div>
+ <?php if ($this->user->hasProjectAccess('ProjectViewController', 'show', $project['id'])): ?>
+ <?= $this->render('project/dropdown', array('project' => $project)) ?>
+ <?php else: ?>
+ <strong><?= '#'.$project['id'] ?></strong>
+ <?php endif ?>
+
+ <span class="table-list-title <?= $project['is_active'] == 0 ? 'status-closed' : '' ?>">
+ <?= $this->url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
+ </span>
+
+ <?php if ($project['is_public']): ?>
+ <i class="fa fa-share-alt fa-fw" title="<?= t('Shared project') ?>"></i>
+ <?php endif ?>
+
+ <?php if ($project['is_private']): ?>
+ <i class="fa fa-lock fa-fw" title="<?= t('Private project') ?>"></i>
+ <?php endif ?>
+
+ <?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
+ <span class="tooltip" title="<?= t('Members') ?>" data-href="<?= $this->url->href('ProjectUserOverviewController', 'users', array('project_id' => $project['id'])) ?>"><i class="fa fa-users"></i></span>&nbsp;
+ <?php endif ?>
+
+ <?php if (! empty($project['description'])): ?>
+ <span class="tooltip" title="<?= $this->text->markdownAttribute($project['description']) ?>">
+ <i class="fa fa-info-circle"></i>
+ </span>
+ <?php endif ?>
+
+ <?php if ($project['is_active'] == 0): ?>
+ <i class="fa fa-ban fa-fw" aria-hidden="true" title="<?= t('Closed') ?>"></i><?= t('Closed') ?>
+ <?php endif ?>
+</div>
diff --git a/app/Template/project_list/show.php b/app/Template/project_list/show.php
deleted file mode 100644
index 9a804588..00000000
--- a/app/Template/project_list/show.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<section id="main">
- <div class="page-header">
- <ul>
- <?= $this->hook->render('template:project-list:menu:before') ?>
-
- <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
- <li>
- <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
- </li>
- <?php endif ?>
- <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
- <li>
- <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
- </li>
- <?php endif ?>
-
- <?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
- <li><?= $this->url->icon('user', t('Users overview'), 'ProjectUserOverviewController', 'managers') ?></li>
- <?php endif ?>
-
- <?php if ($this->user->hasAccess('ProjectGanttController', 'show')): ?>
- <li><?= $this->url->icon('sliders', t('Projects Gantt chart'), 'ProjectGanttController', 'show') ?></li>
- <?php endif ?>
-
- <?= $this->hook->render('template:project-list:menu:after') ?>
- </ul>
- </div>
- <?php if ($paginator->isEmpty()): ?>
- <p class="alert"><?= t('No project') ?></p>
- <?php else: ?>
- <table class="table-striped table-scrolling">
- <tr>
- <th class="column-5"><?= $paginator->order(t('Id'), 'id') ?></th>
- <th class="column-8"><?= $paginator->order(t('Status'), 'is_active') ?></th>
- <th class="column-15"><?= $paginator->order(t('Project'), 'name') ?></th>
- <th class="column-10"><?= $paginator->order(t('Start date'), 'start_date') ?></th>
- <th class="column-10"><?= $paginator->order(t('End date'), 'end_date') ?></th>
- <th class="column-15"><?= $paginator->order(t('Owner'), 'owner_id') ?></th>
- <?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
- <th class="column-10"><?= t('Users') ?></th>
- <?php endif ?>
- <th><?= t('Columns') ?></th>
- </tr>
- <?php foreach ($paginator->getCollection() as $project): ?>
- <tr>
- <td>
- <?= $this->render('project/dropdown', array('project' => $project)) ?>
- </td>
- <td>
- <?php if ($project['is_active']): ?>
- <?= t('Open') ?>
- <?php else: ?>
- <?= t('Closed') ?>
- <?php endif ?>
- </td>
- <td>
- <?= $this->url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
-
- <?php if ($project['is_public']): ?>
- <i class="fa fa-share-alt fa-fw" title="<?= t('Shared project') ?>"></i>
- <?php endif ?>
- <?php if ($project['is_private']): ?>
- <i class="fa fa-lock fa-fw" title="<?= t('Private project') ?>"></i>
- <?php endif ?>
-
- <?php if (! empty($project['description'])): ?>
- <span class="tooltip" title="<?= $this->text->markdownAttribute($project['description']) ?>">
- <i class="fa fa-info-circle"></i>
- </span>
- <?php endif ?>
- </td>
- <td>
- <?= $this->dt->date($project['start_date']) ?>
- </td>
- <td>
- <?= $this->dt->date($project['end_date']) ?>
- </td>
- <td>
- <?php if ($project['owner_id'] > 0): ?>
- <?= $this->text->e($project['owner_name'] ?: $project['owner_username']) ?>
- <?php endif ?>
- </td>
- <?php if ($this->user->hasAccess('ProjectUserOverviewController', 'managers')): ?>
- <td>
- <i class="fa fa-users fa-fw"></i>
- <span class="tooltip" title="<?= t('Members') ?>" data-href="<?= $this->url->href('ProjectUserOverviewController', 'users', array('project_id' => $project['id'])) ?>"><?= t('Members') ?></span>
- </td>
- <?php endif ?>
- <td class="dashboard-project-stats">
- <?php foreach ($project['columns'] as $column): ?>
- <strong title="<?= t('Task count') ?>"><?= $column['nb_open_tasks'] ?></strong>
- <small><?= $this->text->e($column['title']) ?></small>
- <?php endforeach ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
-
- <?= $paginator ?>
- <?php endif ?>
-</section>
diff --git a/app/Template/project_list/sort_menu.php b/app/Template/project_list/sort_menu.php
new file mode 100644
index 00000000..290822fc
--- /dev/null
+++ b/app/Template/project_list/sort_menu.php
@@ -0,0 +1,26 @@
+<div class="dropdown">
+ <a href="#" class="dropdown-menu dropdown-menu-link-icon"><strong><?= t('Sort') ?> <i class="fa fa-caret-down"></i></strong></a>
+ <ul>
+ <li>
+ <?= $paginator->order(t('Project ID'), \Kanboard\Model\ProjectModel::TABLE.'.id') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Project name'), \Kanboard\Model\ProjectModel::TABLE.'.name') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Status'), \Kanboard\Model\ProjectModel::TABLE.'.is_active') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Start date'), \Kanboard\Model\ProjectModel::TABLE.'.start_date') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('End date'), \Kanboard\Model\ProjectModel::TABLE.'.end_date') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Public'), \Kanboard\Model\ProjectModel::TABLE.'.is_public') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Private'), \Kanboard\Model\ProjectModel::TABLE.'.is_private') ?>
+ </li>
+ </ul>
+</div>
diff --git a/app/Template/task_list/header.php b/app/Template/task_list/header.php
new file mode 100644
index 00000000..fb05dbdc
--- /dev/null
+++ b/app/Template/task_list/header.php
@@ -0,0 +1,12 @@
+<div class="table-list-header">
+ <div class="table-list-header-count">
+ <?php if ($paginator->getTotal() > 1): ?>
+ <?= t('%d tasks', $paginator->getTotal()) ?>
+ <?php else: ?>
+ <?= t('%d task', $paginator->getTotal()) ?>
+ <?php endif ?>
+ </div>
+ <div class="table-list-header-menu">
+ <?= $this->render('task_list/sort_menu', array('paginator' => $paginator)) ?>
+ </div>
+</div> \ No newline at end of file
diff --git a/app/Template/task_list/listing.php b/app/Template/task_list/listing.php
new file mode 100644
index 00000000..171c148d
--- /dev/null
+++ b/app/Template/task_list/listing.php
@@ -0,0 +1,33 @@
+<section id="main">
+ <?= $this->projectHeader->render($project, 'TaskListController', 'show') ?>
+
+ <?php if ($paginator->isEmpty()): ?>
+ <p class="alert"><?= t('No tasks found.') ?></p>
+ <?php elseif (! $paginator->isEmpty()): ?>
+ <div class="table-list">
+ <?= $this->render('task_list/header', array('paginator' => $paginator)) ?>
+ <?php foreach ($paginator->getCollection() as $task): ?>
+ <div class="table-list-row color-<?= $task['color_id'] ?>">
+ <?= $this->render('task_list/task_title', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_details', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_avatars', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_icons', array(
+ 'project' => $project,
+ 'task' => $task,
+ )) ?>
+ </div>
+ <?php endforeach ?>
+ </div>
+
+ <?= $paginator ?>
+ <?php endif ?>
+</section>
diff --git a/app/Template/task_list/show.php b/app/Template/task_list/show.php
deleted file mode 100644
index 8454d13f..00000000
--- a/app/Template/task_list/show.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<section id="main">
- <?= $this->projectHeader->render($project, 'TaskListController', 'show') ?>
-
- <?php if ($paginator->isEmpty()): ?>
- <p class="alert"><?= t('No tasks found.') ?></p>
- <?php elseif (! $paginator->isEmpty()): ?>
- <table class="table-striped table-scrolling table-small">
- <tr>
- <th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
- <th class="column-10"><?= $paginator->order(t('Swimlane'), 'tasks.swimlane_id') ?></th>
- <th class="column-10"><?= $paginator->order(t('Column'), 'tasks.column_id') ?></th>
- <th class="column-10"><?= $paginator->order(t('Category'), 'tasks.category_id') ?></th>
- <th class="column-6"><?= $paginator->order(t('Priority'), \Kanboard\Model\TaskModel::TABLE.'.priority') ?></th>
- <th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
- <th class="column-10"><?= $paginator->order(t('Assignee'), 'users.username') ?></th>
- <th class="column-10"><?= $paginator->order(t('Due date'), 'tasks.date_due') ?></th>
- <th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
- </tr>
- <?php foreach ($paginator->getCollection() as $task): ?>
- <tr>
- <td class="color-<?= $task['color_id'] ?>">
- <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?>
- <?= $this->render('task/dropdown', array('task' => $task)) ?>
- <?php else: ?>
- #<?= $task['id'] ?>
- <?php endif ?>
- </td>
- <td>
- <?= $this->text->e($task['swimlane_name']) ?>
- </td>
- <td>
- <?= $this->text->e($task['column_name']) ?>
- </td>
- <td>
- <?= $this->text->e($task['category_name']) ?>
- </td>
- <td>
- P<?= $this->text->e($task['priority'])?>
- </td>
- <td>
- <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
- </td>
- <td>
- <?php if ($task['assignee_username']): ?>
- <?= $this->text->e($task['assignee_name'] ?: $task['assignee_username']) ?>
- <?php else: ?>
- <?= t('Unassigned') ?>
- <?php endif ?>
- </td>
- <td>
- <?= $this->dt->date($task['date_due']) ?>
- </td>
- <td>
- <?php if ($task['is_active'] == \Kanboard\Model\TaskModel::STATUS_OPEN): ?>
- <?= t('Open') ?>
- <?php else: ?>
- <?= t('Closed') ?>
- <?php endif ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
-
- <?= $paginator ?>
- <?php endif ?>
-</section>
diff --git a/app/Template/task_list/sort_menu.php b/app/Template/task_list/sort_menu.php
new file mode 100644
index 00000000..48081fe0
--- /dev/null
+++ b/app/Template/task_list/sort_menu.php
@@ -0,0 +1,32 @@
+<div class="dropdown">
+ <a href="#" class="dropdown-menu dropdown-menu-link-icon"><strong><?= t('Sort') ?> <i class="fa fa-caret-down"></i></strong></a>
+ <ul>
+ <li>
+ <?= $paginator->order(t('Task ID'), \Kanboard\Model\TaskModel::TABLE.'.id') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Swimlane'), 'swimlane_name') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Column'), 'column_name') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Category'), 'category_name') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Priority'), \Kanboard\Model\TaskModel::TABLE.'.priority') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Title'), \Kanboard\Model\TaskModel::TABLE.'.title') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Assignee'), 'assignee_name') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Due date'), \Kanboard\Model\TaskModel::TABLE.'.date_due') ?>
+ </li>
+ <li>
+ <?= $paginator->order(t('Status'), \Kanboard\Model\TaskModel::TABLE.'.is_active') ?>
+ </li>
+ </ul>
+</div>
diff --git a/app/Template/task_list/task_avatars.php b/app/Template/task_list/task_avatars.php
new file mode 100644
index 00000000..143fd8ea
--- /dev/null
+++ b/app/Template/task_list/task_avatars.php
@@ -0,0 +1,20 @@
+<?php if (! empty($task['owner_id'])): ?>
+ <div class="task-list-avatars">
+ <span
+ <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?>
+ class="task-board-change-assignee"
+ data-url="<?= $this->url->href('TaskModificationController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>">
+ <?php else: ?>
+ class="task-board-assignee">
+ <?php endif ?>
+ <?= $this->avatar->small(
+ $task['owner_id'],
+ $task['assignee_username'],
+ $task['assignee_name'],
+ $task['assignee_email'],
+ $task['assignee_avatar_path'],
+ 'avatar-inline'
+ ) ?><span class="task-avatar-assignee"><?= $this->text->e($task['assignee_name'] ?: $task['assignee_username']) ?></span>
+ </span>
+ </div>
+<?php endif ?>
diff --git a/app/Template/task_list/task_details.php b/app/Template/task_list/task_details.php
new file mode 100644
index 00000000..78b7ede7
--- /dev/null
+++ b/app/Template/task_list/task_details.php
@@ -0,0 +1,23 @@
+<div class="table-list-details">
+ <?= $this->text->e($task['project_name']) ?> &gt;
+ <?= $this->text->e($task['swimlane_name']) ?> &gt;
+ <?= $this->text->e($task['column_name']) ?>
+
+ <?php if (! empty($task['category_id'])): ?>
+ <span class="task-list-category">
+ <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?>
+ <?= $this->url->link(
+ $this->text->e($task['category_name']),
+ 'TaskModificationController',
+ 'edit',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id']),
+ false,
+ 'js-modal-medium' . (! empty($task['category_description']) ? ' tooltip' : ''),
+ ! empty($task['category_description']) ? $this->text->markdownAttribute($task['category_description']) : t('Change category')
+ ) ?>
+ <?php else: ?>
+ <?= $this->text->e($task['category_name']) ?>
+ <?php endif ?>
+ </span>
+ <?php endif ?>
+</div>
diff --git a/app/Template/task_list/task_icons.php b/app/Template/task_list/task_icons.php
new file mode 100644
index 00000000..da08a43f
--- /dev/null
+++ b/app/Template/task_list/task_icons.php
@@ -0,0 +1,94 @@
+<div class="task-list-icons">
+ <?php if ($task['reference']): ?>
+ <span class="task-board-reference" title="<?= t('Reference') ?>">
+ <?= $this->text->e($task['reference']) ?>
+ </span>
+ <?php endif ?>
+ <?php if ($task['is_milestone'] == 1): ?>
+ <span title="<?= t('Milestone') ?>">
+ <i class="fa fa-flag flag-milestone"></i>
+ </span>
+ <?php endif ?>
+
+ <?php if ($task['score']): ?>
+ <span class="task-score" title="<?= t('Complexity') ?>">
+ <i class="fa fa-trophy"></i>
+ <?= $this->text->e($task['score']) ?>
+ </span>
+ <?php endif ?>
+
+ <?php if (! empty($task['time_estimated']) || ! empty($task['time_spent'])): ?>
+ <span class="task-time-estimated" title="<?= t('Time spent and estimated') ?>">
+ <?= $this->text->e($task['time_spent']) ?>/<?= $this->text->e($task['time_estimated']) ?>h
+ </span>
+ <?php endif ?>
+
+ <?php if (! empty($task['date_due'])): ?>
+ <span class="task-date
+ <?php if (date('Y-m-d') == date('Y-m-d', $task['date_due'])): ?>
+ task-date-today
+ <?php elseif (time() > $task['date_due']): ?>
+ task-date-overdue
+ <?php endif ?>
+ ">
+ <i class="fa fa-calendar"></i>
+ <?= $this->dt->date($task['date_due']) ?>
+ </span>
+ <?php endif ?>
+
+ <?php if ($task['recurrence_status'] == \Kanboard\Model\TaskModel::RECURRING_STATUS_PENDING): ?>
+ <span title="<?= t('Recurrence') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'recurrence', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-refresh fa-rotate-90"></i></span>
+ <?php endif ?>
+
+ <?php if ($task['recurrence_status'] == \Kanboard\Model\TaskModel::RECURRING_STATUS_PROCESSED): ?>
+ <span title="<?= t('Recurrence') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'recurrence', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-refresh fa-rotate-90 fa-inverse"></i></span>
+ <?php endif ?>
+
+ <?php if (! empty($task['nb_links'])): ?>
+ <span title="<?= t('Links') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'tasklinks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-code-fork fa-fw"></i><?= $task['nb_links'] ?></span>
+ <?php endif ?>
+
+ <?php if (! empty($task['nb_external_links'])): ?>
+ <span title="<?= t('External links') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'externallinks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-external-link fa-fw"></i><?= $task['nb_external_links'] ?></span>
+ <?php endif ?>
+
+ <?php if (! empty($task['nb_subtasks'])): ?>
+ <span title="<?= t('Sub-Tasks') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'subtasks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-bars"></i>&nbsp;<?= round($task['nb_completed_subtasks']/$task['nb_subtasks']*100, 0).'%' ?></span>
+ <?php endif ?>
+
+ <?php if (! empty($task['nb_files'])): ?>
+ <span title="<?= t('Attachments') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'attachments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-paperclip"></i>&nbsp;<?= $task['nb_files'] ?></span>
+ <?php endif ?>
+
+ <?php if ($task['nb_comments'] > 0): ?>
+ <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?>
+ <?= $this->modal->medium(
+ 'comments-o',
+ $task['nb_comments'],
+ 'CommentListController',
+ 'show',
+ array('task_id' => $task['id'], 'project_id' => $task['project_id']),
+ $task['nb_comments'] == 1 ? t('%d comment', $task['nb_comments']) : t('%d comments', $task['nb_comments'])
+ ) ?>
+ <?php else: ?>
+ <span title="<?= $task['nb_comments'] == 1 ? t('%d comment', $task['nb_comments']) : t('%d comments', $task['nb_comments']) ?>"><i class="fa fa-comments-o"></i>&nbsp;<?= $task['nb_comments'] ?></span>
+ <?php endif ?>
+ <?php endif ?>
+
+ <?php if (! empty($task['description'])): ?>
+ <span title="<?= t('Description') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'description', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>">
+ <i class="fa fa-file-text-o"></i>
+ </span>
+ <?php endif ?>
+
+ <?php if ($task['is_active'] == 1): ?>
+ <div class="task-icon-age">
+ <span title="<?= t('Task age in days')?>" class="task-icon-age-total"><?= $this->dt->age($task['date_creation']) ?></span>
+ <span title="<?= t('Days in this column')?>" class="task-icon-age-column"><?= $this->dt->age($task['date_moved']) ?></span>
+ </div>
+ <?php else: ?>
+ <span class="task-board-closed"><i class="fa fa-ban fa-fw"></i><?= t('Closed') ?></span>
+ <?php endif ?>
+
+ <?= $this->task->formatPriority($project, $task) ?>
+</div>
diff --git a/app/Template/task_list/task_title.php b/app/Template/task_list/task_title.php
new file mode 100644
index 00000000..028e9b70
--- /dev/null
+++ b/app/Template/task_list/task_title.php
@@ -0,0 +1,11 @@
+<div>
+ <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?>
+ <?= $this->render('task/dropdown', array('task' => $task)) ?>
+ <?php else: ?>
+ <strong><?= '#'.$task['id'] ?></strong>
+ <?php endif ?>
+
+ <span class="table-list-title <?= $task['is_active'] == 0 ? 'status-closed' : '' ?>">
+ <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])) ?>
+ </span>
+</div>