Add tasks in bulk from the board
This commit is contained in:
parent
a1a48b8374
commit
10f662ce07
|
|
@ -1,3 +1,11 @@
|
|||
Version 1.0.29 (unreleased)
|
||||
--------------
|
||||
|
||||
New features:
|
||||
|
||||
* Add tasks in bulk from the board
|
||||
|
||||
|
||||
Version 1.0.28
|
||||
--------------
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Controller;
|
||||
|
||||
/**
|
||||
* Class TaskBulk
|
||||
*
|
||||
* @package Kanboard\Controller
|
||||
*/
|
||||
class TaskBulk extends Base
|
||||
{
|
||||
/**
|
||||
* Show the form
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $errors
|
||||
*/
|
||||
public function show(array $values = array(), array $errors = array())
|
||||
{
|
||||
$project = $this->getProject();
|
||||
|
||||
if (empty($values)) {
|
||||
$values = array(
|
||||
'swimlane_id' => $this->request->getIntegerParam('swimlane_id'),
|
||||
'column_id' => $this->request->getIntegerParam('column_id'),
|
||||
'project_id' => $project['id'],
|
||||
);
|
||||
}
|
||||
|
||||
$this->response->html($this->template->render('task_bulk/show', array(
|
||||
'project' => $project,
|
||||
'values' => $values,
|
||||
'errors' => $errors,
|
||||
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id'], true, false, true),
|
||||
'colors_list' => $this->color->getList(),
|
||||
'categories_list' => $this->category->getList($project['id']),
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all tasks in the database
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$values = $this->request->getValues();
|
||||
list($valid, $errors) = $this->taskValidator->validateBulkCreation($values);
|
||||
|
||||
if ($valid) {
|
||||
$this->createTasks($project, $values);
|
||||
$this->response->redirect($this->helper->url->to(
|
||||
'Board',
|
||||
'show',
|
||||
array('project_id' => $project['id']),
|
||||
'swimlane-'. $values['swimlane_id']
|
||||
), true);
|
||||
} else {
|
||||
$this->show($values, $errors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all tasks
|
||||
*
|
||||
* @param array $project
|
||||
* @param array $values
|
||||
*/
|
||||
protected function createTasks(array $project, array $values)
|
||||
{
|
||||
$tasks = preg_split('/\r\n|[\r\n]/', $values['tasks']);
|
||||
|
||||
foreach ($tasks as $title) {
|
||||
$title = trim($title);
|
||||
|
||||
if (! empty($title)) {
|
||||
$this->taskCreation->create(array(
|
||||
'title' => $title,
|
||||
'column_id' => $values['column_id'],
|
||||
'swimlane_id' => $values['swimlane_id'],
|
||||
'category_id' => empty($values['category_id']) ? 0 : $values['category_id'],
|
||||
'owner_id' => empty($values['owner_id']) ? 0 : $values['owner_id'],
|
||||
'color_id' => $values['color_id'],
|
||||
'project_id' => $project['id'],
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -79,6 +79,6 @@ class Taskcreation extends Base
|
|||
));
|
||||
}
|
||||
|
||||
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])));
|
||||
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])), true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,11 +35,17 @@
|
|||
<i class="fa fa-minus-square fa-fw"></i>
|
||||
<a href="#" class="board-toggle-column-view" data-column-id="<?= $column['id'] ?>"><?= t('Hide this column') ?></a>
|
||||
</li>
|
||||
<?php if ($this->user->hasProjectAccess('BoardPopover', 'closeColumnTasks', $column['project_id']) && $column['nb_tasks'] > 0): ?>
|
||||
<?php if ($this->user->hasProjectAccess('Taskcreation', 'create', $column['project_id'])): ?>
|
||||
<li>
|
||||
<i class="fa fa-close fa-fw"></i>
|
||||
<?= $this->url->link(t('Close all tasks of this column'), 'BoardPopover', 'confirmCloseColumnTasks', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
|
||||
<i class="fa fa-align-justify" aria-hidden="true"></i>
|
||||
<?= $this->url->link(t('Create tasks in bulk'), 'TaskBulk', 'show', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
|
||||
</li>
|
||||
<?php if ($column['nb_tasks'] > 0): ?>
|
||||
<li>
|
||||
<i class="fa fa-close fa-fw"></i>
|
||||
<?= $this->url->link(t('Close all tasks of this column'), 'BoardPopover', 'confirmCloseColumnTasks', array('project_id' => $column['project_id'], 'column_id' => $column['id'], 'swimlane_id' => $swimlane['id']), false, 'popover') ?>
|
||||
</li>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</ul>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
<div class="page-header">
|
||||
<h2><?= t('Create tasks in bulk') ?></h2>
|
||||
</div>
|
||||
|
||||
<form class="popover-form" method="post" action="<?= $this->url->href('TaskBulk', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
|
||||
<?= $this->form->csrf() ?>
|
||||
<?= $this->form->hidden('column_id', $values) ?>
|
||||
<?= $this->form->hidden('swimlane_id', $values) ?>
|
||||
<?= $this->form->hidden('project_id', $values) ?>
|
||||
|
||||
<?= $this->task->selectAssignee($users_list, $values, $errors) ?>
|
||||
<?= $this->task->selectCategory($categories_list, $values, $errors) ?>
|
||||
|
||||
<?= $this->form->label(t('Tasks'), 'tasks') ?>
|
||||
<?= $this->form->textarea('tasks', $values, $errors, array(
|
||||
'placeholder="'.implode("\r\n", array(t('My task title'), t('My task title'), t('My task title'))).'"')
|
||||
) ?>
|
||||
<p class="form-help"><?= t('Enter one task by line.') ?></p>
|
||||
|
||||
<?= $this->render('task/color_picker', array('colors_list' => $colors_list, 'values' => $values)) ?>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||
<?= t('or') ?> <?= $this->url->link(t('cancel'), 'board', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
@ -69,6 +69,32 @@ class TaskValidator extends Base
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate task creation
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Form values
|
||||
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
|
||||
*/
|
||||
public function validateBulkCreation(array $values)
|
||||
{
|
||||
$rules = array(
|
||||
new Validators\Required('project_id', t('The project is required')),
|
||||
new Validators\Required('tasks', t('Field required')),
|
||||
new Validators\Required('column_id', t('Field required')),
|
||||
new Validators\Required('swimlane_id', t('Field required')),
|
||||
new Validators\Integer('category_id', t('This value must be an integer')),
|
||||
new Validators\Integer('swimlane_id', t('This value must be an integer')),
|
||||
);
|
||||
|
||||
$v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
|
||||
|
||||
return array(
|
||||
$v->execute(),
|
||||
$v->getErrors()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate description creation
|
||||
*
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,10 +67,13 @@ Kanboard.Popover.prototype.close = function(e) {
|
|||
Kanboard.Popover.prototype.ajaxReload = function(data, request, self) {
|
||||
var redirect = request.getResponseHeader("X-Ajax-Redirect");
|
||||
|
||||
if (redirect) {
|
||||
window.location = redirect === 'self' ? window.location.href.split("#")[0] : redirect;
|
||||
}
|
||||
else {
|
||||
if (redirect === 'self') {
|
||||
window.location.reload();
|
||||
} else if (redirect && redirect.indexOf('#') > -1) {
|
||||
window.location = redirect.split('#')[0];
|
||||
} else if (redirect) {
|
||||
window.location = redirect;
|
||||
} else {
|
||||
$("#popover-content").html(data);
|
||||
$("#popover-content input[autofocus]").focus();
|
||||
self.executeOnOpenedListeners();
|
||||
|
|
|
|||
Loading…
Reference in New Issue