Add timer for subtasks and remove settings for subtask time tracking
This commit is contained in:
@@ -42,7 +42,7 @@ class Config extends Base
|
||||
|
||||
switch ($redirect) {
|
||||
case 'project':
|
||||
$values += array('subtask_restriction' => 0, 'subtask_time_tracking' => 0);
|
||||
$values += array('subtask_restriction' => 0);
|
||||
break;
|
||||
case 'integrations':
|
||||
$values += array('integration_slack_webhook' => 0, 'integration_hipchat' => 0, 'integration_gravatar' => 0, 'integration_jabber' => 0);
|
||||
|
||||
@@ -256,7 +256,7 @@ class Subtask extends Base
|
||||
case 'dashboard':
|
||||
$this->response->redirect($this->helper->url->to('app', 'index'));
|
||||
default:
|
||||
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
|
||||
$this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#subtasks');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
35
app/Controller/Timer.php
Normal file
35
app/Controller/Timer.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
* Time Tracking controller
|
||||
*
|
||||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Timer extends Base
|
||||
{
|
||||
/**
|
||||
* Start/stop timer for subtasks
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function subtask()
|
||||
{
|
||||
$project_id = $this->request->getIntegerParam('project_id');
|
||||
$task_id = $this->request->getIntegerParam('task_id');
|
||||
$subtask_id = $this->request->getIntegerParam('subtask_id');
|
||||
$timer = $this->request->getStringParam('timer');
|
||||
|
||||
if ($timer === 'start') {
|
||||
$this->subtaskTimeTracking->logStartTime($subtask_id, $this->userSession->getId());
|
||||
}
|
||||
else if ($timer === 'stop') {
|
||||
$this->subtaskTimeTracking->logEndTime($subtask_id, $this->userSession->getId());
|
||||
$this->subtaskTimeTracking->updateTaskTimeTracking($task_id);
|
||||
}
|
||||
|
||||
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $project_id, 'task_id' => $task_id)).'#subtasks');
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,39 @@ namespace Helper;
|
||||
*/
|
||||
class Datetime extends \Core\Base
|
||||
{
|
||||
/**
|
||||
* Get the age of an item in quasi human readable format.
|
||||
* It's in this format: <1h , NNh, NNd
|
||||
*
|
||||
* @access public
|
||||
* @param integer $timestamp Unix timestamp of the artifact for which age will be calculated
|
||||
* @param integer $now Compare with this timestamp (Default value is the current unix timestamp)
|
||||
* @return string
|
||||
*/
|
||||
public function age($timestamp, $now = null)
|
||||
{
|
||||
if ($now === null) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
$diff = $now - $timestamp;
|
||||
|
||||
if ($diff < 900) {
|
||||
return t('<15m');
|
||||
}
|
||||
if ($diff < 1200) {
|
||||
return t('<30m');
|
||||
}
|
||||
else if ($diff < 3600) {
|
||||
return t('<1h');
|
||||
}
|
||||
else if ($diff < 86400) {
|
||||
return '~'.t('%dh', $diff / 3600);
|
||||
}
|
||||
|
||||
return t('%dd', ($now - $timestamp) / 86400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all hours for day
|
||||
*
|
||||
|
||||
@@ -10,33 +10,6 @@ namespace Helper;
|
||||
*/
|
||||
class Task extends \Core\Base
|
||||
{
|
||||
/**
|
||||
* Get the age of an item in quasi human readable format.
|
||||
* It's in this format: <1h , NNh, NNd
|
||||
*
|
||||
* @access public
|
||||
* @param integer $timestamp Unix timestamp of the artifact for which age will be calculated
|
||||
* @param integer $now Compare with this timestamp (Default value is the current unix timestamp)
|
||||
* @return string
|
||||
*/
|
||||
public function age($timestamp, $now = null)
|
||||
{
|
||||
if ($now === null) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
$diff = $now - $timestamp;
|
||||
|
||||
if ($diff < 3600) {
|
||||
return t('<1h');
|
||||
}
|
||||
else if ($diff < 86400) {
|
||||
return t('%dh', $diff / 3600);
|
||||
}
|
||||
|
||||
return t('%dd', ($now - $timestamp) / 86400);
|
||||
}
|
||||
|
||||
public function getColors()
|
||||
{
|
||||
return $this->color->getList();
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
// 'User dashboard' => '',
|
||||
// 'Allow only one subtask in progress at the same time for a user' => '',
|
||||
// 'Edit column "%s"' => '',
|
||||
// 'Enable time tracking for subtasks' => '',
|
||||
// 'Select the new status of the subtask: "%s"' => '',
|
||||
// 'Subtask timesheet' => '',
|
||||
// 'There is nothing to show.' => '',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Benutzer Dashboard',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Erlaube nur eine Teilaufgabe pro Benutzer zu bearbeiten',
|
||||
'Edit column "%s"' => 'Spalte "%s" bearbeiten',
|
||||
'Enable time tracking for subtasks' => 'Aktiviere Zeiterfassung für Teilaufgaben',
|
||||
'Select the new status of the subtask: "%s"' => 'Wähle einen neuen Status für Teilaufgabe: "%s"',
|
||||
'Subtask timesheet' => 'Teilaufgaben Zeiterfassung',
|
||||
'There is nothing to show.' => 'Es ist nichts zum Anzeigen vorhanden.',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Tablero de usuario',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Permitir sólo una subtarea en progreso a la vez para cada usuario',
|
||||
'Edit column "%s"' => 'Editar columna %s',
|
||||
'Enable time tracking for subtasks' => 'Activar seguimiento temporal para subtareas',
|
||||
'Select the new status of the subtask: "%s"' => 'Seleccionar el nuevo estado de la subtarea: "%s"',
|
||||
'Subtask timesheet' => 'Hoja temporal de subtarea',
|
||||
'There is nothing to show.' => 'Nada que mostrar',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
// 'User dashboard' => '',
|
||||
// 'Allow only one subtask in progress at the same time for a user' => '',
|
||||
// 'Edit column "%s"' => '',
|
||||
// 'Enable time tracking for subtasks' => '',
|
||||
// 'Select the new status of the subtask: "%s"' => '',
|
||||
// 'Subtask timesheet' => '',
|
||||
// 'There is nothing to show.' => '',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -616,7 +616,6 @@ return array(
|
||||
'User dashboard' => 'Tableau de bord de l\'utilisateur',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Autoriser une seule sous-tâche en progrès en même temps pour un utilisateur',
|
||||
'Edit column "%s"' => 'Modifier la colonne « %s »',
|
||||
'Enable time tracking for subtasks' => 'Activer la feuille de temps pour les sous-tâches',
|
||||
'Select the new status of the subtask: "%s"' => 'Selectionnez le nouveau statut de la sous-tâche : « %s »',
|
||||
'Subtask timesheet' => 'Feuille de temps des sous-tâches',
|
||||
'There is nothing to show.' => 'Il n\'y a rien à montrer.',
|
||||
@@ -948,4 +947,8 @@ return array(
|
||||
'%%Y-%%m-%%d' => '%%d/%%m/%%Y',
|
||||
'Total for all columns' => 'Total pour toutes les colonnes',
|
||||
'You need at least 2 days of data to show the chart.' => 'Vous avez besoin d\'au minimum 2 jours de données pour afficher le graphique.',
|
||||
'<15m' => '<15m',
|
||||
'<30m' => '<30m',
|
||||
'Stop timer' => 'Stopper le chrono',
|
||||
'Start timer' => 'Démarrer le chrono',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Felhasználói vezérlőpult',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Egyszerre csak egy folyamatban levő részfeladat engedélyezése a felhasználóknak',
|
||||
'Edit column "%s"' => 'Oszlop szerkesztés: %s',
|
||||
'Enable time tracking for subtasks' => 'Idő követés engedélyezése a részfeladatokhoz',
|
||||
'Select the new status of the subtask: "%s"' => 'Részfeladat állapot változtatás: %s',
|
||||
'Subtask timesheet' => 'Részfeladat idővonal',
|
||||
'There is nothing to show.' => 'Nincs megjelenítendő adat.',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Bacheca utente',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Permetti un solo sotto-compito in progresso per utente nello stesso tempo',
|
||||
'Edit column "%s"' => 'Modifica la colonna "%s"',
|
||||
'Enable time tracking for subtasks' => 'Abilita la gestione del tempo per i sotto-compiti',
|
||||
'Select the new status of the subtask: "%s"' => 'Selziona il nuovo status per il sotto-compito: "%s"',
|
||||
'Subtask timesheet' => 'Timesheet del sotto-compito',
|
||||
'There is nothing to show.' => 'Nulla da mostrare.',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'ユーザダッシュボード',
|
||||
'Allow only one subtask in progress at the same time for a user' => '一人のユーザにつき一つのタスクのみ進行中にできます',
|
||||
'Edit column "%s"' => 'カラム「%s」の編集',
|
||||
'Enable time tracking for subtasks' => 'サブタスクのタイムトラッキングを有効',
|
||||
'Select the new status of the subtask: "%s"' => 'サブタスク「%s」のステータスを選択',
|
||||
'Subtask timesheet' => 'サブタスクタイムシート',
|
||||
'There is nothing to show.' => '何も表示するものがありません。',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Gebruiker dashboard',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Sta maximaal één subtaak in behandeling toe per gebruiker',
|
||||
'Edit column "%s"' => 'Kolom « %s » aanpassen',
|
||||
'Enable time tracking for subtasks' => 'Activeer tijdschrijven voor subtaken',
|
||||
'Select the new status of the subtask: "%s"' => 'Selecteer nieuwe status voor subtaak : « %s »',
|
||||
'Subtask timesheet' => 'Subtaak timesheet',
|
||||
'There is nothing to show.' => 'Er is niets om te laten zijn.',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Panel użytkownika',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Zezwalaj na tylko jedno pod-zadanie o statusie "w trakcie" jednocześnie',
|
||||
'Edit column "%s"' => 'Zmień kolumnę "%s"',
|
||||
'Enable time tracking for subtasks' => 'Włącz śledzenie czasu dla pod-zadań',
|
||||
'Select the new status of the subtask: "%s"' => 'Wybierz nowy status dla pod-zadania: "%s"',
|
||||
'Subtask timesheet' => 'Oś czasu pod-zadania',
|
||||
'There is nothing to show.' => 'Nie nic do wyświetlenia',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Painel de Controle do usuário',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Permitir apenas uma subtarefa em andamento ao mesmo tempo para um usuário',
|
||||
'Edit column "%s"' => 'Editar a coluna "%s"',
|
||||
'Enable time tracking for subtasks' => 'Ativar a gestão de tempo par a subtarefa',
|
||||
'Select the new status of the subtask: "%s"' => 'Selecionar um novo status para a subtarefa: "%s"',
|
||||
'Subtask timesheet' => 'Gestão de tempo das subtarefas',
|
||||
'There is nothing to show.' => 'Não há nada para mostrar',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Пользователь панели мониторинга',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Разрешена только одна подзадача в разработке одновременно для одного пользователя',
|
||||
'Edit column "%s"' => 'Редактировать колонку "%s"',
|
||||
'Enable time tracking for subtasks' => 'Включить учет времени для подзадач',
|
||||
'Select the new status of the subtask: "%s"' => 'Выбрать новый статус для подзадачи: "%s"',
|
||||
'Subtask timesheet' => 'Табель времени подзадач',
|
||||
'There is nothing to show.' => 'Здесь ничего нет.',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Korisnički panel',
|
||||
// 'Allow only one subtask in progress at the same time for a user' => '',
|
||||
// 'Edit column "%s"' => '',
|
||||
// 'Enable time tracking for subtasks' => '',
|
||||
// 'Select the new status of the subtask: "%s"' => '',
|
||||
// 'Subtask timesheet' => '',
|
||||
'There is nothing to show.' => 'Nema podataka',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Användardashboard',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Tillåt endast en deluppgift igång samtidigt för en användare',
|
||||
'Edit column "%s"' => 'Ändra kolumn "%s"',
|
||||
'Enable time tracking for subtasks' => 'Aktivera tidsbevakning för deluppgifter',
|
||||
'Select the new status of the subtask: "%s"' => 'Välj ny status för deluppgiften: "%s"',
|
||||
'Subtask timesheet' => 'Tidrapport för deluppgiften',
|
||||
'There is nothing to show.' => 'Det finns inget att visa',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'ผู้ใช้แดชบอร์ด',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'อนุญาตให้ทำงานย่อยได้เพียงงานเดียวต่อหนึ่งคนในเวลาเดียวกัน',
|
||||
'Edit column "%s"' => 'แก้ไขคอลัมน์ "%s"',
|
||||
'Enable time tracking for subtasks' => 'สามารถติดตามเวลาของงานย่อย',
|
||||
'Select the new status of the subtask: "%s"' => 'เลือกสถานะใหม่ของงานย่อย: "%s"',
|
||||
'Subtask timesheet' => 'เวลางานย่อย',
|
||||
'There is nothing to show.' => 'ไม่มีที่ต้องแสดง',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => 'Kullanıcı Anasayfası',
|
||||
'Allow only one subtask in progress at the same time for a user' => 'Bir kullanıcı için aynı anda yalnızca bir alt göreve izin ver',
|
||||
'Edit column "%s"' => '"%s" sütununu değiştir',
|
||||
'Enable time tracking for subtasks' => 'Alt görevler için zaman takibini etkinleştir',
|
||||
'Select the new status of the subtask: "%s"' => '"%s" alt görevi için yeni durum seçin.',
|
||||
'Subtask timesheet' => 'Alt görev için zaman takip tablosu',
|
||||
'There is nothing to show.' => 'Gösterilecek hiçbir şey yok.',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -614,7 +614,6 @@ return array(
|
||||
'User dashboard' => '用户仪表板',
|
||||
'Allow only one subtask in progress at the same time for a user' => '每用户同时仅有一个活动子任务',
|
||||
'Edit column "%s"' => '编辑栏目"%s"',
|
||||
'Enable time tracking for subtasks' => '启用子任务的时间记录',
|
||||
'Select the new status of the subtask: "%s"' => '选择子任务的新状态:"%s"',
|
||||
'Subtask timesheet' => '子任务时间',
|
||||
'There is nothing to show.' => '无内容。',
|
||||
@@ -946,4 +945,8 @@ return array(
|
||||
// '%%Y-%%m-%%d' => '',
|
||||
// 'Total for all columns' => '',
|
||||
// 'You need at least 2 days of data to show the chart.' => '',
|
||||
// '<15m' => '',
|
||||
// '<30m' => '',
|
||||
// 'Stop timer' => '',
|
||||
// 'Start timer' => '',
|
||||
);
|
||||
|
||||
@@ -41,6 +41,7 @@ class Acl extends Base
|
||||
'subtask' => '*',
|
||||
'task' => '*',
|
||||
'tasklink' => '*',
|
||||
'timer' => '*',
|
||||
'calendar' => array('show', 'project'),
|
||||
);
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class Budget extends Base
|
||||
->join(Task::TABLE, 'id', 'task_id', Subtask::TABLE)
|
||||
->join(User::TABLE, 'id', 'user_id')
|
||||
->eq(Task::TABLE.'.project_id', $project_id)
|
||||
->filter(array($this, 'applyUserRate'));
|
||||
->callback(array($this, 'applyUserRate'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -276,7 +276,7 @@ class Project extends Base
|
||||
return $this->db
|
||||
->table(Project::TABLE)
|
||||
->in('id', $project_ids)
|
||||
->filter(array($this, 'applyColumnStats'));
|
||||
->callback(array($this, 'applyColumnStats'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,6 +78,8 @@ class Subtask extends Base
|
||||
|
||||
foreach ($subtasks as &$subtask) {
|
||||
$subtask['status_name'] = $status[$subtask['status']];
|
||||
$subtask['timer_start_date'] = isset($subtask['timer_start_date']) ? $subtask['timer_start_date'] : 0;
|
||||
$subtask['is_timer_started'] = ! empty($subtask['timer_start_date']);
|
||||
}
|
||||
|
||||
return $subtasks;
|
||||
@@ -101,12 +103,13 @@ class Subtask extends Base
|
||||
Task::TABLE.'.title AS task_name',
|
||||
Project::TABLE.'.name AS project_name'
|
||||
)
|
||||
->subquery($this->subtaskTimeTracking->getTimerQuery($user_id), 'timer_start_date')
|
||||
->eq('user_id', $user_id)
|
||||
->eq(Project::TABLE.'.is_active', Project::ACTIVE)
|
||||
->in(Subtask::TABLE.'.status', $status)
|
||||
->join(Task::TABLE, 'id', 'task_id')
|
||||
->join(Project::TABLE, 'id', 'project_id', Task::TABLE)
|
||||
->filter(array($this, 'addStatusName'));
|
||||
->callback(array($this, 'addStatusName'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,10 +124,15 @@ class Subtask extends Base
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq('task_id', $task_id)
|
||||
->columns(self::TABLE.'.*', User::TABLE.'.username', User::TABLE.'.name')
|
||||
->columns(
|
||||
self::TABLE.'.*',
|
||||
User::TABLE.'.username',
|
||||
User::TABLE.'.name'
|
||||
)
|
||||
->subquery($this->subtaskTimeTracking->getTimerQuery($this->userSession->getId()), 'timer_start_date')
|
||||
->join(User::TABLE, 'id', 'user_id')
|
||||
->asc(self::TABLE.'.position')
|
||||
->filter(array($this, 'addStatusName'))
|
||||
->callback(array($this, 'addStatusName'))
|
||||
->findAll();
|
||||
}
|
||||
|
||||
@@ -144,8 +152,9 @@ class Subtask extends Base
|
||||
->table(self::TABLE)
|
||||
->eq(self::TABLE.'.id', $subtask_id)
|
||||
->columns(self::TABLE.'.*', User::TABLE.'.username', User::TABLE.'.name')
|
||||
->subquery($this->subtaskTimeTracking->getTimerQuery($this->userSession->getId()), 'timer_start_date')
|
||||
->join(User::TABLE, 'id', 'user_id')
|
||||
->filter(array($this, 'addStatusName'))
|
||||
->callback(array($this, 'addStatusName'))
|
||||
->findOne();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,27 @@ class SubtaskTimeTracking extends Base
|
||||
*/
|
||||
const TABLE = 'subtask_time_tracking';
|
||||
|
||||
/**
|
||||
* Get query to check if a timer is started for the given user and subtask
|
||||
*
|
||||
* @access public
|
||||
* @param integer $user_id User id
|
||||
* @return string
|
||||
*/
|
||||
public function getTimerQuery($user_id)
|
||||
{
|
||||
return sprintf(
|
||||
"SELECT %s FROM %s WHERE %s='%d' AND %s='0' AND %s=%s",
|
||||
$this->db->escapeIdentifier('start'),
|
||||
$this->db->escapeIdentifier(self::TABLE),
|
||||
$this->db->escapeIdentifier('user_id'),
|
||||
$user_id,
|
||||
$this->db->escapeIdentifier('end'),
|
||||
$this->db->escapeIdentifier('subtask_id'),
|
||||
Subtask::TABLE.'.id'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query for user timesheet (pagination)
|
||||
*
|
||||
@@ -217,7 +238,7 @@ class SubtaskTimeTracking extends Base
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->insert(array('subtask_id' => $subtask_id, 'user_id' => $user_id, 'start' => time()));
|
||||
->insert(array('subtask_id' => $subtask_id, 'user_id' => $user_id, 'start' => time(), 'end' => 0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -301,7 +301,7 @@ class TaskFilter extends Base
|
||||
*/
|
||||
public function toAutoCompletion()
|
||||
{
|
||||
return $this->query->columns('id', 'title')->filter(function(array $results) {
|
||||
return $this->query->columns('id', 'title')->callback(function(array $results) {
|
||||
|
||||
foreach ($results as &$result) {
|
||||
$result['value'] = $result['title'];
|
||||
|
||||
@@ -316,7 +316,7 @@ class TaskFinder extends Base
|
||||
->table(Task::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->eq('column_id', $column_id)
|
||||
->in('is_active', 1)
|
||||
->eq('is_active', 1)
|
||||
->count();
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ class TaskFinder extends Base
|
||||
->eq('project_id', $project_id)
|
||||
->eq('column_id', $column_id)
|
||||
->eq('swimlane_id', $swimlane_id)
|
||||
->in('is_active', 1)
|
||||
->eq('is_active', 1)
|
||||
->count();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,12 @@ use PDO;
|
||||
use Core\Security;
|
||||
use Model\Link;
|
||||
|
||||
const VERSION = 75;
|
||||
const VERSION = 76;
|
||||
|
||||
function version_76($pdo)
|
||||
{
|
||||
$pdo->exec("DELETE FROM `settings` WHERE `option`='subtask_time_tracking'");
|
||||
}
|
||||
|
||||
function version_75($pdo)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,12 @@ use PDO;
|
||||
use Core\Security;
|
||||
use Model\Link;
|
||||
|
||||
const VERSION = 55;
|
||||
const VERSION = 56;
|
||||
|
||||
function version_56($pdo)
|
||||
{
|
||||
$pdo->exec('DELETE FROM "settings" WHERE "option"=\'subtask_time_tracking\'');
|
||||
}
|
||||
|
||||
function version_55($pdo)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,12 @@ use Core\Security;
|
||||
use PDO;
|
||||
use Model\Link;
|
||||
|
||||
const VERSION = 72;
|
||||
const VERSION = 73;
|
||||
|
||||
function version_73($pdo)
|
||||
{
|
||||
$pdo->exec("DELETE FROM settings WHERE option='subtask_time_tracking'");
|
||||
}
|
||||
|
||||
function version_72($pdo)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ use Subscriber\ProjectActivitySubscriber;
|
||||
use Subscriber\ProjectDailySummarySubscriber;
|
||||
use Subscriber\ProjectModificationDateSubscriber;
|
||||
use Subscriber\WebhookSubscriber;
|
||||
use Subscriber\SubtaskTimesheetSubscriber;
|
||||
use Subscriber\SubtaskTimeTrackingSubscriber;
|
||||
use Subscriber\TaskMovedDateSubscriber;
|
||||
use Subscriber\TransitionSubscriber;
|
||||
use Subscriber\RecurringTaskSubscriber;
|
||||
@@ -29,7 +29,7 @@ class EventDispatcherProvider implements ServiceProviderInterface
|
||||
$container['dispatcher']->addSubscriber(new ProjectModificationDateSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new WebhookSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new NotificationSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new SubtaskTimesheetSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new SubtaskTimeTrackingSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new TaskMovedDateSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new TransitionSubscriber($container));
|
||||
$container['dispatcher']->addSubscriber(new RecurringTaskSubscriber($container));
|
||||
|
||||
@@ -6,7 +6,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Model\Subtask;
|
||||
use Event\SubtaskEvent;
|
||||
|
||||
class SubtaskTimesheetSubscriber extends \Core\Base implements EventSubscriberInterface
|
||||
class SubtaskTimeTrackingSubscriber extends \Core\Base implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
@@ -28,7 +28,7 @@ class SubtaskTimesheetSubscriber extends \Core\Base implements EventSubscriberIn
|
||||
|
||||
public function logStartEnd(SubtaskEvent $event)
|
||||
{
|
||||
if ($this->config->get('subtask_time_tracking') == 1 && isset($event['status'])) {
|
||||
if (isset($event['status'])) {
|
||||
|
||||
$subtask = $this->subtask->getById($event['id']);
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
</span>
|
||||
|
||||
<div class="task-board-days">
|
||||
<span title="<?= t('Task age in days')?>" class="task-days-age"><?= $this->task->age($task['date_creation']) ?></span>
|
||||
<span title="<?= t('Days in this column')?>" class="task-days-incolumn"><?= $this->task->age($task['date_moved']) ?></span>
|
||||
<span title="<?= t('Task age in days')?>" class="task-days-age"><?= $this->datetime->age($task['date_creation']) ?></span>
|
||||
<span title="<?= t('Days in this column')?>" class="task-days-incolumn"><?= $this->datetime->age($task['date_moved']) ?></span>
|
||||
</div>
|
||||
|
||||
<div class="task-board-title">
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<p class="form-help"><?= t('Example: "Bug, Feature Request, Improvement"') ?></p>
|
||||
|
||||
<?= $this->form->checkbox('subtask_restriction', t('Allow only one subtask in progress at the same time for a user'), 1, $values['subtask_restriction'] == 1) ?>
|
||||
<?= $this->form->checkbox('subtask_time_tracking', t('Enable time tracking for subtasks'), 1, $values['subtask_time_tracking'] == 1) ?>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
|
||||
|
||||
@@ -33,13 +33,29 @@
|
||||
<?php endif ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (! empty($subtask['time_spent'])): ?>
|
||||
<strong><?= $this->e($subtask['time_spent']).'h' ?></strong> <?= t('spent') ?>
|
||||
<?php endif ?>
|
||||
<ul class="no-bullet">
|
||||
<li>
|
||||
<?php if (! empty($subtask['time_spent'])): ?>
|
||||
<strong><?= $this->e($subtask['time_spent']).'h' ?></strong> <?= t('spent') ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (! empty($subtask['time_estimated'])): ?>
|
||||
<strong><?= $this->e($subtask['time_estimated']).'h' ?></strong> <?= t('estimated') ?>
|
||||
<?php endif ?>
|
||||
<?php if (! empty($subtask['time_estimated'])): ?>
|
||||
<strong><?= $this->e($subtask['time_estimated']).'h' ?></strong> <?= t('estimated') ?>
|
||||
<?php endif ?>
|
||||
</li>
|
||||
<?php if (! isset($not_editable) && $subtask['user_id'] == $this->user->getId()): ?>
|
||||
<li>
|
||||
<?php if ($subtask['is_timer_started']): ?>
|
||||
<i class="fa fa-pause"></i>
|
||||
<?= $this->url->link(t('Stop timer'), 'timer', 'subtask', array('timer' => 'stop', 'project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'])) ?>
|
||||
(<?= $this->datetime->age($subtask['timer_start_date']) ?>)
|
||||
<?php else: ?>
|
||||
<i class="fa fa-play-circle-o"></i>
|
||||
<?= $this->url->link(t('Start timer'), 'timer', 'subtask', array('timer' => 'start', 'project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'])) ?>
|
||||
<?php endif ?>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
</ul>
|
||||
</td>
|
||||
<?php if (! isset($not_editable)): ?>
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user