Add subtasks
This commit is contained in:
@@ -23,6 +23,7 @@ use Model\LastLogin;
|
||||
* @property \Model\Ldap $ldap
|
||||
* @property \Model\Project $project
|
||||
* @property \Model\RememberMe $rememberMe
|
||||
* @property \Model\SubTask $subTask
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\User $user
|
||||
*/
|
||||
|
||||
185
app/Controller/Subtask.php
Normal file
185
app/Controller/Subtask.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
* SubTask controller
|
||||
*
|
||||
* @package controller
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class Subtask extends Base
|
||||
{
|
||||
/**
|
||||
* Get the current subtask
|
||||
*
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
private function getSubtask()
|
||||
{
|
||||
$subtask = $this->subTask->getById($this->request->getIntegerParam('subtask_id'));
|
||||
|
||||
if (! $subtask) {
|
||||
$this->notfound();
|
||||
}
|
||||
|
||||
return $subtask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation form
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
|
||||
$this->response->html($this->taskLayout('subtask_create', array(
|
||||
'values' => array(
|
||||
'task_id' => $task['id'],
|
||||
),
|
||||
'errors' => array(),
|
||||
'users_list' => $this->project->getUsersList($task['project_id']),
|
||||
'task' => $task,
|
||||
'menu' => 'tasks',
|
||||
'title' => t('Add a sub-task')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation and creation
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$values = $this->request->getValues();
|
||||
|
||||
list($valid, $errors) = $this->subTask->validate($values);
|
||||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->subTask->create($values)) {
|
||||
$this->session->flash(t('Sub-task added successfully.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to create your sub-task.'));
|
||||
}
|
||||
|
||||
if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
|
||||
$this->response->redirect('?controller=subtask&action=create&task_id='.$task['id']);
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
}
|
||||
|
||||
$this->response->html($this->taskLayout('subtask_create', array(
|
||||
'values' => $values,
|
||||
'errors' => $errors,
|
||||
'users_list' => $this->project->getUsersList($task['project_id']),
|
||||
'task' => $task,
|
||||
'menu' => 'tasks',
|
||||
'title' => t('Add a sub-task')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit form
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$subtask = $this->getSubTask();
|
||||
|
||||
$this->response->html($this->taskLayout('subtask_edit', array(
|
||||
'values' => $subtask,
|
||||
'errors' => array(),
|
||||
'users_list' => $this->project->getUsersList($task['project_id']),
|
||||
'status_list' => $this->subTask->getStatusList(),
|
||||
'subtask' => $subtask,
|
||||
'task' => $task,
|
||||
'menu' => 'tasks',
|
||||
'title' => t('Edit a sub-task')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update and validate a subtask
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$subtask = $this->getSubtask();
|
||||
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->subTask->validate($values);
|
||||
|
||||
if ($valid) {
|
||||
|
||||
if ($this->subTask->update($values)) {
|
||||
$this->session->flash(t('Sub-task updated successfully.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to update your sub-task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
}
|
||||
|
||||
$this->response->html($this->taskLayout('subtask_edit', array(
|
||||
'values' => $values,
|
||||
'errors' => $errors,
|
||||
'users_list' => $this->project->getUsersList($task['project_id']),
|
||||
'status_list' => $this->subTask->getStatusList(),
|
||||
'subtask' => $subtask,
|
||||
'task' => $task,
|
||||
'menu' => 'tasks',
|
||||
'title' => t('Edit a sub-task')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation dialog before removing a subtask
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$subtask = $this->getSubtask();
|
||||
|
||||
$this->response->html($this->taskLayout('subtask_remove', array(
|
||||
'subtask' => $subtask,
|
||||
'task' => $task,
|
||||
'menu' => 'tasks',
|
||||
'title' => t('Remove a sub-task')
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a subtask
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$subtask = $this->getSubtask();
|
||||
|
||||
if ($this->subTask->remove($subtask['id'])) {
|
||||
$this->session->flash(t('Sub-task removed successfully.'));
|
||||
}
|
||||
else {
|
||||
$this->session->flashError(t('Unable to remove this sub-task.'));
|
||||
}
|
||||
|
||||
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ class Task extends Base
|
||||
$this->response->html($this->taskLayout('task_show', array(
|
||||
'files' => $this->file->getAll($task['id']),
|
||||
'comments' => $this->comment->getAll($task['id']),
|
||||
'subtasks' => $this->subTask->getAll($task['id']),
|
||||
'task' => $task,
|
||||
'columns_list' => $this->board->getColumnsList($task['project_id']),
|
||||
'colors_list' => $this->task->getColors(),
|
||||
|
||||
@@ -346,4 +346,29 @@ return array(
|
||||
// 'Add a comment' => '',
|
||||
// 'Edit a comment' => '',
|
||||
// 'Summary' => '',
|
||||
// 'Time tracking' => '',
|
||||
// 'Estimate:' => '',
|
||||
// 'Spent:' => '',
|
||||
// 'Do you really want to remove this sub-task?' => '',
|
||||
// 'Remaining:' => '',
|
||||
// 'hours' => '',
|
||||
// 'spent' => '',
|
||||
// 'estimated' => '',
|
||||
// 'Sub-Tasks' => '',
|
||||
// 'Add a sub-task' => '',
|
||||
// 'Original Estimate' => '',
|
||||
// 'Create another sub-task' => '',
|
||||
// 'Time Spent' => '',
|
||||
// 'Edit a sub-task' => '',
|
||||
// 'Remove a sub-task' => '',
|
||||
// 'The time must be a numeric value' => '',
|
||||
// 'Todo' => '',
|
||||
// 'In progress' => '',
|
||||
// 'Done' => '',
|
||||
// 'Sub-task removed successfully.' => '',
|
||||
// 'Unable to remove this sub-task.' => '',
|
||||
// 'Sub-task updated successfully.' => '',
|
||||
// 'Unable to update your sub-task.' => '',
|
||||
// 'Unable to create your sub-task.' => '',
|
||||
// 'Sub-task added successfully.' => '',
|
||||
);
|
||||
|
||||
@@ -344,4 +344,29 @@ return array(
|
||||
// 'Add a comment' => '',
|
||||
// 'Edit a comment' => '',
|
||||
// 'Summary' => '',
|
||||
// 'Time tracking' => '',
|
||||
// 'Estimate:' => '',
|
||||
// 'Spent:' => '',
|
||||
// 'Do you really want to remove this sub-task?' => '',
|
||||
// 'Remaining:' => '',
|
||||
// 'hours' => '',
|
||||
// 'spent' => '',
|
||||
// 'estimated' => '',
|
||||
// 'Sub-Tasks' => '',
|
||||
// 'Add a sub-task' => '',
|
||||
// 'Original Estimate' => '',
|
||||
// 'Create another sub-task' => '',
|
||||
// 'Time Spent' => '',
|
||||
// 'Edit a sub-task' => '',
|
||||
// 'Remove a sub-task' => '',
|
||||
// 'The time must be a numeric value' => '',
|
||||
// 'Todo' => '',
|
||||
// 'In progress' => '',
|
||||
// 'Done' => '',
|
||||
// 'Sub-task removed successfully.' => '',
|
||||
// 'Unable to remove this sub-task.' => '',
|
||||
// 'Sub-task updated successfully.' => '',
|
||||
// 'Unable to update your sub-task.' => '',
|
||||
// 'Unable to create your sub-task.' => '',
|
||||
// 'Sub-task added successfully.' => '',
|
||||
);
|
||||
|
||||
@@ -344,4 +344,29 @@ return array(
|
||||
'Add a comment' => 'Ajouter un commentaire',
|
||||
'Edit a comment' => 'Modifier un commentaire',
|
||||
'Summary' => 'Résumé',
|
||||
'Time tracking' => 'Gestion du temps',
|
||||
'Estimate:' => 'Estimation :',
|
||||
'Spent:' => 'Passé :',
|
||||
'Do you really want to remove this sub-task?' => 'Voulez-vous vraiment supprimer cette sous-tâche ?',
|
||||
'Remaining:' => 'Restant :',
|
||||
'hours' => 'heures',
|
||||
'spent' => 'passé',
|
||||
'estimated' => 'estimé',
|
||||
'Sub-Tasks' => 'Sous-Tâches',
|
||||
'Add a sub-task' => 'Ajouter une sous-tâche',
|
||||
'Original Estimate' => 'Estimation originale',
|
||||
'Create another sub-task' => 'Créer une autre sous-tâche',
|
||||
'Time Spent' => 'Temps passé',
|
||||
'Edit a sub-task' => 'Modifier une sous-tâche',
|
||||
'Remove a sub-task' => 'Supprimer une sous-tâche',
|
||||
'The time must be a numeric value' => 'Le temps doit-être une valeur numérique',
|
||||
'Todo' => 'À faire',
|
||||
'In progress' => 'En cours',
|
||||
'Done' => 'Terminé',
|
||||
'Sub-task removed successfully.' => 'Sous-tâche supprimée avec succès.',
|
||||
'Unable to remove this sub-task.' => 'Impossible de supprimer cette sous-tâche.',
|
||||
'Sub-task updated successfully.' => 'Sous-tâche mise à jour avec succès.',
|
||||
'Unable to update your sub-task.' => 'Impossible de mettre à jour votre sous-tâche.',
|
||||
'Unable to create your sub-task.' => 'Impossible de créer votre sous-tâche.',
|
||||
'Sub-task added successfully.' => 'Sous-tâche ajouté avec succès.',
|
||||
);
|
||||
|
||||
@@ -349,4 +349,29 @@ return array(
|
||||
// 'Add a comment' => '',
|
||||
// 'Edit a comment' => '',
|
||||
// 'Summary' => '',
|
||||
// 'Time tracking' => '',
|
||||
// 'Estimate:' => '',
|
||||
// 'Spent:' => '',
|
||||
// 'Do you really want to remove this sub-task?' => '',
|
||||
// 'Remaining:' => '',
|
||||
// 'hours' => '',
|
||||
// 'spent' => '',
|
||||
// 'estimated' => '',
|
||||
// 'Sub-Tasks' => '',
|
||||
// 'Add a sub-task' => '',
|
||||
// 'Original Estimate' => '',
|
||||
// 'Create another sub-task' => '',
|
||||
// 'Time Spent' => '',
|
||||
// 'Edit a sub-task' => '',
|
||||
// 'Remove a sub-task' => '',
|
||||
// 'The time must be a numeric value' => '',
|
||||
// 'Todo' => '',
|
||||
// 'In progress' => '',
|
||||
// 'Done' => '',
|
||||
// 'Sub-task removed successfully.' => '',
|
||||
// 'Unable to remove this sub-task.' => '',
|
||||
// 'Sub-task updated successfully.' => '',
|
||||
// 'Unable to update your sub-task.' => '',
|
||||
// 'Unable to create your sub-task.' => '',
|
||||
// 'Sub-task added successfully.' => '',
|
||||
);
|
||||
|
||||
@@ -345,4 +345,29 @@ return array(
|
||||
// 'Add a comment' => '',
|
||||
// 'Edit a comment' => '',
|
||||
// 'Summary' => '',
|
||||
// 'Time tracking' => '',
|
||||
// 'Estimate:' => '',
|
||||
// 'Spent:' => '',
|
||||
// 'Do you really want to remove this sub-task?' => '',
|
||||
// 'Remaining:' => '',
|
||||
// 'hours' => '',
|
||||
// 'spent' => '',
|
||||
// 'estimated' => '',
|
||||
// 'Sub-Tasks' => '',
|
||||
// 'Add a sub-task' => '',
|
||||
// 'Original Estimate' => '',
|
||||
// 'Create another sub-task' => '',
|
||||
// 'Time Spent' => '',
|
||||
// 'Edit a sub-task' => '',
|
||||
// 'Remove a sub-task' => '',
|
||||
// 'The time must be a numeric value' => '',
|
||||
// 'Todo' => '',
|
||||
// 'In progress' => '',
|
||||
// 'Done' => '',
|
||||
// 'Sub-task removed successfully.' => '',
|
||||
// 'Unable to remove this sub-task.' => '',
|
||||
// 'Sub-task updated successfully.' => '',
|
||||
// 'Unable to update your sub-task.' => '',
|
||||
// 'Unable to create your sub-task.' => '',
|
||||
// 'Sub-task added successfully.' => '',
|
||||
);
|
||||
|
||||
@@ -14,6 +14,7 @@ require __DIR__.'/../../vendor/SimpleValidator/Validators/AlphaNumeric.php';
|
||||
require __DIR__.'/../../vendor/SimpleValidator/Validators/GreaterThan.php';
|
||||
require __DIR__.'/../../vendor/SimpleValidator/Validators/Date.php';
|
||||
require __DIR__.'/../../vendor/SimpleValidator/Validators/Email.php';
|
||||
require __DIR__.'/../../vendor/SimpleValidator/Validators/Numeric.php';
|
||||
|
||||
use Core\Event;
|
||||
use PicoDb\Database;
|
||||
|
||||
179
app/Model/SubTask.php
Normal file
179
app/Model/SubTask.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
use SimpleValidator\Validator;
|
||||
use SimpleValidator\Validators;
|
||||
|
||||
/**
|
||||
* Subtask model
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubTask extends Base
|
||||
{
|
||||
/**
|
||||
* SQL table name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TABLE = 'task_has_subtasks';
|
||||
|
||||
/**
|
||||
* Task "done" status
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const STATUS_DONE = 2;
|
||||
|
||||
/**
|
||||
* Task "in progress" status
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const STATUS_INPROGRESS = 1;
|
||||
|
||||
/**
|
||||
* Task "todo" status
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const STATUS_TODO = 0;
|
||||
|
||||
/**
|
||||
* Get available status
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStatusList()
|
||||
{
|
||||
$status = array(
|
||||
self::STATUS_TODO => t('Todo'),
|
||||
self::STATUS_INPROGRESS => t('In progress'),
|
||||
self::STATUS_DONE => t('Done'),
|
||||
);
|
||||
|
||||
asort($status);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all subtasks for a given task
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_id Task id
|
||||
* @return array
|
||||
*/
|
||||
public function getAll($task_id)
|
||||
{
|
||||
$status = $this->getStatusList();
|
||||
$subtasks = $this->db->table(self::TABLE)
|
||||
->eq('task_id', $task_id)
|
||||
->columns(self::TABLE.'.*', User::TABLE.'.username')
|
||||
->join(User::TABLE, 'id', 'user_id')
|
||||
->findAll();
|
||||
|
||||
foreach ($subtasks as &$subtask) {
|
||||
$subtask['status_name'] = $status[$subtask['status']];
|
||||
}
|
||||
|
||||
return $subtasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subtask by the id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $subtask_id Subtask id
|
||||
* @return array
|
||||
*/
|
||||
public function getById($subtask_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $subtask_id)->findOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return bool
|
||||
*/
|
||||
public function create(array $values)
|
||||
{
|
||||
if (isset($values['another_subtask'])) {
|
||||
unset($values['another_subtask']);
|
||||
}
|
||||
|
||||
if (isset($values['time_estimated']) && empty($values['time_estimated'])) {
|
||||
$values['time_estimated'] = 0;
|
||||
}
|
||||
|
||||
if (isset($values['time_spent']) && empty($values['time_spent'])) {
|
||||
$values['time_spent'] = 0;
|
||||
}
|
||||
|
||||
return $this->db->table(self::TABLE)->save($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return bool
|
||||
*/
|
||||
public function update(array $values)
|
||||
{
|
||||
if (isset($values['time_estimated']) && empty($values['time_estimated'])) {
|
||||
$values['time_estimated'] = 0;
|
||||
}
|
||||
|
||||
if (isset($values['time_spent']) && empty($values['time_spent'])) {
|
||||
$values['time_spent'] = 0;
|
||||
}
|
||||
|
||||
return $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove
|
||||
*
|
||||
* @access public
|
||||
* @param integer $subtask_id Subtask id
|
||||
* @return bool
|
||||
*/
|
||||
public function remove($subtask_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $subtask_id)->remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate creation/modification
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validate(array $values)
|
||||
{
|
||||
$v = new Validator($values, array(
|
||||
new Validators\Required('task_id', t('The task id is required')),
|
||||
new Validators\Integer('task_id', t('The task id must be an integer')),
|
||||
new Validators\Required('title', t('The title is required')),
|
||||
new Validators\MaxLength('title', t('The maximum length is %d characters', 100), 100),
|
||||
new Validators\Integer('user_id', t('The user id must be an integer')),
|
||||
new Validators\Integer('status', t('The status must be an integer')),
|
||||
new Validators\Numeric('time_estimated', t('The time must be a numeric value')),
|
||||
new Validators\Numeric('time_spent', t('The time must be a numeric value')),
|
||||
));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,24 @@
|
||||
|
||||
namespace Schema;
|
||||
|
||||
const VERSION = 17;
|
||||
const VERSION = 18;
|
||||
|
||||
function version_18($pdo)
|
||||
{
|
||||
$pdo->exec("
|
||||
CREATE TABLE task_has_subtasks (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
title VARCHAR(255),
|
||||
status INT DEFAULT 0,
|
||||
time_estimated INT DEFAULT 0,
|
||||
time_spent INT DEFAULT 0,
|
||||
task_id INT,
|
||||
user_id INT,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB CHARSET=utf8"
|
||||
);
|
||||
}
|
||||
|
||||
function version_17($pdo)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,23 @@
|
||||
|
||||
namespace Schema;
|
||||
|
||||
const VERSION = 17;
|
||||
const VERSION = 18;
|
||||
|
||||
function version_18($pdo)
|
||||
{
|
||||
$pdo->exec("
|
||||
CREATE TABLE task_has_subtasks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
title TEXT COLLATE NOCASE,
|
||||
status INTEGER DEFAULT 0,
|
||||
time_estimated INTEGER DEFAULT 0,
|
||||
time_spent INTEGER DEFAULT 0,
|
||||
task_id INTEGER,
|
||||
user_id INTEGER,
|
||||
FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE
|
||||
)"
|
||||
);
|
||||
}
|
||||
|
||||
function version_17($pdo)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Add a comment') ?></h2>
|
||||
<h2><?= t('Remove a comment') ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="confirm">
|
||||
|
||||
17
app/Templates/file_show.php
Normal file
17
app/Templates/file_show.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Attachments') ?></h2>
|
||||
</div>
|
||||
|
||||
<ul class="task-show-files">
|
||||
<?php foreach ($files as $file): ?>
|
||||
<li>
|
||||
<a href="?controller=file&action=download&file_id=<?= $file['id'] ?>&task_id=<?= $task['id'] ?>"><?= Helper\escape($file['name']) ?></a>
|
||||
<span class="task-show-file-actions">
|
||||
<?php if ($file['is_image']): ?>
|
||||
<a href="?controller=file&action=open&file_id=<?= $file['id'] ?>&task_id=<?= $task['id'] ?>" class="popover"><?= t('open') ?></a>,
|
||||
<?php endif ?>
|
||||
<a href="?controller=file&action=confirm&file_id=<?= $file['id'] ?>&task_id=<?= $task['id'] ?>"><?= t('remove') ?></a>
|
||||
</span>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
25
app/Templates/subtask_create.php
Normal file
25
app/Templates/subtask_create.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Add a sub-task') ?></h2>
|
||||
</div>
|
||||
|
||||
<form method="post" action="?controller=subtask&action=save&task_id=<?= $task['id'] ?>" autocomplete="off">
|
||||
|
||||
<?= Helper\form_hidden('task_id', $values) ?>
|
||||
|
||||
<?= Helper\form_label(t('Title'), 'title') ?>
|
||||
<?= Helper\form_text('title', $values, $errors, array('required autofocus')) ?><br/>
|
||||
|
||||
<?= Helper\form_label(t('Assignee'), 'user_id') ?>
|
||||
<?= Helper\form_select('user_id', $users_list, $values, $errors) ?><br/>
|
||||
|
||||
<?= Helper\form_label(t('Original Estimate'), 'time_estimated') ?>
|
||||
<?= Helper\form_numeric('time_estimated', $values, $errors) ?> <?= t('hours') ?><br/>
|
||||
|
||||
<?= Helper\form_checkbox('another_subtask', t('Create another sub-task'), 1, isset($values['another_subtask']) && $values['another_subtask'] == 1) ?>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
|
||||
<?= t('or') ?>
|
||||
<a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
||||
</div>
|
||||
</form>
|
||||
30
app/Templates/subtask_edit.php
Normal file
30
app/Templates/subtask_edit.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Edit a sub-task') ?></h2>
|
||||
</div>
|
||||
|
||||
<form method="post" action="?controller=subtask&action=update&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>" autocomplete="off">
|
||||
|
||||
<?= Helper\form_hidden('id', $values) ?>
|
||||
<?= Helper\form_hidden('task_id', $values) ?>
|
||||
|
||||
<?= Helper\form_label(t('Title'), 'title') ?>
|
||||
<?= Helper\form_text('title', $values, $errors, array('required autofocus')) ?><br/>
|
||||
|
||||
<?= Helper\form_label(t('Status'), 'status') ?>
|
||||
<?= Helper\form_select('status', $status_list, $values, $errors) ?><br/>
|
||||
|
||||
<?= Helper\form_label(t('Assignee'), 'user_id') ?>
|
||||
<?= Helper\form_select('user_id', $users_list, $values, $errors) ?><br/>
|
||||
|
||||
<?= Helper\form_label(t('Original Estimate'), 'time_estimated') ?>
|
||||
<?= Helper\form_numeric('time_estimated', $values, $errors) ?> <?= t('hours') ?><br/>
|
||||
|
||||
<?= Helper\form_label(t('Time Spent'), 'time_spent') ?>
|
||||
<?= Helper\form_numeric('time_spent', $values, $errors) ?> <?= t('hours') ?><br/>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
|
||||
<?= t('or') ?>
|
||||
<a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
||||
</div>
|
||||
</form>
|
||||
16
app/Templates/subtask_remove.php
Normal file
16
app/Templates/subtask_remove.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Remove a sub-task') ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="confirm">
|
||||
<p class="alert alert-info">
|
||||
<?= t('Do you really want to remove this sub-task?') ?>
|
||||
</p>
|
||||
|
||||
<p><strong><?= Helper\escape($subtask['title']) ?></strong></p>
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="?controller=subtask&action=remove&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>#subtasks"><?= t('cancel') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
60
app/Templates/subtask_show.php
Normal file
60
app/Templates/subtask_show.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Sub-Tasks') ?></h2>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
$total_spent = 0;
|
||||
$total_estimated = 0;
|
||||
$total_remaining = 0;
|
||||
|
||||
?>
|
||||
|
||||
<table class="subtasks-table">
|
||||
<tr>
|
||||
<th width="40%"><?= t('Title') ?></th>
|
||||
<th><?= t('Status') ?></th>
|
||||
<th><?= t('Assignee') ?></th>
|
||||
<th><?= t('Time tracking') ?></th>
|
||||
<th><?= t('Actions') ?></th>
|
||||
</tr>
|
||||
<?php foreach ($subtasks as $subtask): ?>
|
||||
<tr>
|
||||
<td><?= Helper\escape($subtask['title']) ?></td>
|
||||
<td><?= Helper\escape($subtask['status_name']) ?></td>
|
||||
<td>
|
||||
<?php if (! empty($subtask['username'])): ?>
|
||||
<?= Helper\escape($subtask['username']) ?>
|
||||
<?php endif ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (! empty($subtask['time_spent'])): ?>
|
||||
<strong><?= Helper\escape($subtask['time_spent']).'h' ?></strong> <?= t('spent') ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (! empty($subtask['time_estimated'])): ?>
|
||||
<strong><?= Helper\escape($subtask['time_estimated']).'h' ?></strong> <?= t('estimated') ?>
|
||||
<?php endif ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="?controller=subtask&action=edit&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>"><?= t('Edit') ?></a>
|
||||
<?= t('or') ?>
|
||||
<a href="?controller=subtask&action=confirm&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>"><?= t('Remove') ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$total_estimated += $subtask['time_estimated'];
|
||||
$total_spent += $subtask['time_spent'];
|
||||
$total_remaining = $total_estimated - $total_spent;
|
||||
?>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
|
||||
<div class="subtasks-time-tracking">
|
||||
<h4><?= t('Time tracking') ?></h4>
|
||||
<ul>
|
||||
<li><?= t('Estimate:') ?> <strong><?= Helper\escape($total_estimated) ?></strong> <?= t('hours') ?></li>
|
||||
<li><?= t('Spent:') ?> <strong><?= Helper\escape($total_spent) ?></strong> <?= t('hours') ?></li>
|
||||
<li><?= t('Remaining:') ?> <strong><?= Helper\escape($total_remaining > 0 ? $total_remaining : 0) ?></strong> <?= t('hours') ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -62,23 +62,14 @@
|
||||
|
||||
<?php if (! empty($files)): ?>
|
||||
<div id="attachments" class="task-show-section">
|
||||
<div class="page-header">
|
||||
<h2><?= t('Attachments') ?></h2>
|
||||
</div>
|
||||
<?= Helper\template('file_show', array('task' => $task, 'files' => $files)) ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<ul class="task-show-files">
|
||||
<?php foreach ($files as $file): ?>
|
||||
<li>
|
||||
<a href="?controller=file&action=download&file_id=<?= $file['id'] ?>&task_id=<?= $task['id'] ?>"><?= Helper\escape($file['name']) ?></a>
|
||||
<span class="task-show-file-actions">
|
||||
<?php if ($file['is_image']): ?>
|
||||
<a href="?controller=file&action=open&file_id=<?= $file['id'] ?>&task_id=<?= $task['id'] ?>" class="popover"><?= t('open') ?></a>,
|
||||
<?php endif ?>
|
||||
<a href="?controller=file&action=confirm&file_id=<?= $file['id'] ?>&task_id=<?= $task['id'] ?>"><?= t('remove') ?></a>
|
||||
</span>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
|
||||
<?php if (! empty($subtasks)): ?>
|
||||
<div id="subtasks" class="task-show-section">
|
||||
<?= Helper\template('subtask_show', array('task' => $task, 'subtasks' => $subtasks)) ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<li><a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('Summary') ?></a></li>
|
||||
<li><a href="?controller=task&action=edit&task_id=<?= $task['id'] ?>"><?= t('Edit the task') ?></a></li>
|
||||
<li><a href="?controller=task&action=editDescription&task_id=<?= $task['id'] ?>"><?= t('Edit the description') ?></a></li>
|
||||
<li><a href="?controller=subtask&action=create&task_id=<?= $task['id'] ?>"><?= t('Add a sub-task') ?></a></li>
|
||||
<li><a href="?controller=comment&action=create&task_id=<?= $task['id'] ?>"><?= t('Add a comment') ?></a></li>
|
||||
<li><a href="?controller=file&action=create&task_id=<?= $task['id'] ?>"><?= t('Attach a document') ?></a></li>
|
||||
<li><a href="?controller=task&action=duplicate&project_id=<?= $task['project_id'] ?>&task_id=<?= $task['id'] ?>"><?= t('Duplicate') ?></a></li>
|
||||
|
||||
@@ -260,3 +260,8 @@ function form_number($name, $values = array(), array $errors = array(), array $a
|
||||
{
|
||||
return form_input('number', $name, $values, $errors, $attributes, $class);
|
||||
}
|
||||
|
||||
function form_numeric($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '')
|
||||
{
|
||||
return form_input('text', $name, $values, $errors, $attributes, $class.' form-numeric');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user