Remove default swimlane

This commit is contained in:
Frederic Guillot 2017-02-18 09:42:01 -05:00
parent 0430a09c06
commit de128dbad8
77 changed files with 885 additions and 1159 deletions

View File

@ -9,6 +9,13 @@ Improvements:
* Use contextual menu instead of action column in users management
Breaking changes:
* The concept of "default swimlane" is removed
* Previous default swimlanes are migrated to an independent swimlane
* Columns "default_swimlane" and "show_default_swimlane" from "projects" table are not used anymore
* Remove API method "getDefaultSwimlane()"
Bug fixes:
* Hiding subtasks from hidden tasks in dashboard

View File

@ -3,6 +3,7 @@
namespace Kanboard\Api\Procedure;
use Kanboard\Api\Authorization\ProjectAuthorization;
use Kanboard\Model\SwimlaneModel;
/**
* Swimlane API controller
@ -15,7 +16,7 @@ class SwimlaneProcedure extends BaseProcedure
public function getActiveSwimlanes($project_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getActiveSwimlanes', $project_id);
return $this->swimlaneModel->getSwimlanes($project_id);
return $this->swimlaneModel->getAllByStatus($project_id, SwimlaneModel::ACTIVE);
}
public function getAllSwimlanes($project_id)
@ -42,16 +43,10 @@ class SwimlaneProcedure extends BaseProcedure
return $this->swimlaneModel->getById($swimlane_id);
}
public function getDefaultSwimlane($project_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getDefaultSwimlane', $project_id);
return $this->swimlaneModel->getDefault($project_id);
}
public function addSwimlane($project_id, $name, $description = '')
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addSwimlane', $project_id);
return $this->swimlaneModel->create(array('project_id' => $project_id, 'name' => $name, 'description' => $description));
return $this->swimlaneModel->create($project_id, $name, $description);
}
public function updateSwimlane($swimlane_id, $name, $description = null)

View File

@ -68,7 +68,7 @@ class TaskProcedure extends BaseProcedure
return $this->taskModel->remove($task_id);
}
public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0)
public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskPosition', $project_id);
return $this->taskPositionModel->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id);
@ -87,7 +87,7 @@ class TaskProcedure extends BaseProcedure
}
public function createTask($title, $project_id, $color_id = '', $column_id = 0, $owner_id = 0, $creator_id = 0,
$date_due = '', $description = '', $category_id = 0, $score = 0, $swimlane_id = 0, $priority = 0,
$date_due = '', $description = '', $category_id = 0, $score = 0, $swimlane_id = null, $priority = 0,
$recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0,
$recurrence_basedate = 0, $reference = '', array $tags = array(), $date_started = '')
{

View File

@ -25,7 +25,7 @@ class BoardPopoverController extends BaseController
'project' => $project,
'nb_tasks' => $this->taskFinderModel->countByColumnAndSwimlaneId($project['id'], $column_id, $swimlane_id),
'column' => $this->columnModel->getColumnTitleById($column_id),
'swimlane' => $this->swimlaneModel->getNameById($swimlane_id) ?: t($project['default_swimlane']),
'swimlane' => $this->swimlaneModel->getNameById($swimlane_id),
'values' => array('column_id' => $column_id, 'swimlane_id' => $swimlane_id),
)));
}
@ -41,7 +41,7 @@ class BoardPopoverController extends BaseController
$values = $this->request->getValues();
$this->taskStatusModel->closeTasksBySwimlaneAndColumn($values['swimlane_id'], $values['column_id']);
$this->flash->success(t('All tasks of the column "%s" and the swimlane "%s" have been closed successfully.', $this->columnModel->getColumnTitleById($values['column_id']), $this->swimlaneModel->getNameById($values['swimlane_id']) ?: t($project['default_swimlane'])));
$this->flash->success(t('All tasks of the column "%s" and the swimlane "%s" have been closed successfully.', $this->columnModel->getColumnTitleById($values['column_id']), $this->swimlaneModel->getNameById($values['swimlane_id'])));
$this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id'])));
}
}

View File

@ -42,7 +42,6 @@ class SwimlaneController extends BaseController
$project = $this->getProject();
$this->response->html($this->helper->layout->project('swimlane/index', array(
'default_swimlane' => $this->swimlaneModel->getDefault($project['id']),
'active_swimlanes' => $this->swimlaneModel->getAllByStatus($project['id'], SwimlaneModel::ACTIVE),
'inactive_swimlanes' => $this->swimlaneModel->getAllByStatus($project['id'], SwimlaneModel::INACTIVE),
'project' => $project,
@ -81,59 +80,16 @@ class SwimlaneController extends BaseController
list($valid, $errors) = $this->swimlaneValidator->validateCreation($values);
if ($valid) {
if ($this->swimlaneModel->create($values) !== false) {
if ($this->swimlaneModel->create($project['id'], $values['name'], $values['description']) !== false) {
$this->flash->success(t('Your swimlane have been created successfully.'));
return $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])));
$this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])), true);
return;
} else {
$errors = array('name' => array(t('Another swimlane with the same name exists in the project')));
}
}
return $this->create($values, $errors);
}
/**
* Edit default swimlane (display the form)
*
* @access public
* @param array $values
* @param array $errors
* @throws \Kanboard\Core\Controller\PageNotFoundException
*/
public function editDefault(array $values = array(), array $errors = array())
{
$project = $this->getProject();
$swimlane = $this->swimlaneModel->getDefault($project['id']);
$this->response->html($this->helper->layout->project('swimlane/edit_default', array(
'values' => empty($values) ? $swimlane : $values,
'errors' => $errors,
'project' => $project,
)));
}
/**
* Change the default swimlane
*
* @access public
*/
public function updateDefault()
{
$project = $this->getProject();
$values = $this->request->getValues() + array('show_default_swimlane' => 0);
list($valid, $errors) = $this->swimlaneValidator->validateDefaultModification($values);
if ($valid) {
if ($this->swimlaneModel->updateDefault($values)) {
$this->flash->success(t('The default swimlane have been updated successfully.'));
return $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])), true);
} else {
$this->flash->failure(t('Unable to update this swimlane.'));
}
}
return $this->editDefault($values, $errors);
$this->create($values, $errors);
}
/**
@ -236,25 +192,6 @@ class SwimlaneController extends BaseController
$this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])));
}
/**
* Disable default swimlane
*
* @access public
*/
public function disableDefault()
{
$this->checkCSRFParam();
$project = $this->getProject();
if ($this->swimlaneModel->disableDefault($project['id'])) {
$this->flash->success(t('Swimlane updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this swimlane.'));
}
$this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])));
}
/**
* Enable a swimlane
*
@ -275,25 +212,6 @@ class SwimlaneController extends BaseController
$this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])));
}
/**
* Enable default swimlane
*
* @access public
*/
public function enableDefault()
{
$this->checkCSRFParam();
$project = $this->getProject();
if ($this->swimlaneModel->enableDefault($project['id'])) {
$this->flash->success(t('Swimlane updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this swimlane.'));
}
$this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])));
}
/**
* Move swimlane position
*

View File

@ -60,8 +60,14 @@ class TaskCreationController extends BaseController
$this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id'])), true);
} else {
$task_id = $this->taskCreationModel->create($values);
if ($task_id > 0) {
$this->flash->success(t('Task created successfully.'));
$this->afterSave($project, $values, $task_id);
} else {
$this->flash->failure(t('Unable to create this task.'));
$this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id'])), true);
}
}
}

View File

@ -31,11 +31,10 @@ class TaskExport extends Base
{
$tasks = $this->getTasks($project_id, $from, $to);
$colors = $this->colorModel->getList();
$defaultSwimlane = $this->swimlaneModel->getDefault($project_id);
$results = array($this->getColumns());
foreach ($tasks as &$task) {
$task = $this->format($task, $defaultSwimlane['default_swimlane'], $colors);
$task = $this->format($task, $colors);
$results[] = array_values($task);
}
@ -104,16 +103,14 @@ class TaskExport extends Base
*
* @access protected
* @param array $task
* @param string $defaultSwimlaneName
* @param array $colors
* @return array
*/
protected function format(array &$task, $defaultSwimlaneName, array $colors)
protected function format(array &$task, array $colors)
{
$task['is_active'] = $task['is_active'] == TaskModel::STATUS_OPEN ? e('Open') : e('Closed');
$task['color_id'] = $colors[$task['color_id']];
$task['score'] = $task['score'] ?: 0;
$task['swimlane_name'] = $task['swimlane_name'] ?: $defaultSwimlaneName;
$task = $this->dateParser->format(
$task,

View File

@ -36,12 +36,9 @@ class TaskSwimlaneFilter extends BaseFilter implements FilterInterface
{
if (is_int($this->value) || ctype_digit($this->value)) {
$this->query->eq(TaskModel::TABLE.'.swimlane_id', $this->value);
} elseif ($this->value === 'default') {
$this->query->eq(TaskModel::TABLE.'.swimlane_id', 0);
} else {
$this->query->beginOr();
$this->query->ilike(SwimlaneModel::TABLE.'.name', $this->value);
$this->query->ilike(ProjectModel::TABLE.'.default_swimlane', $this->value);
$this->query->closeOr();
}

View File

@ -3,6 +3,7 @@
namespace Kanboard\Formatter;
use Kanboard\Core\Filter\FormatterInterface;
use Kanboard\Model\SwimlaneModel;
use Kanboard\Model\TaskModel;
/**
@ -42,7 +43,7 @@ class BoardFormatter extends BaseFormatter implements FormatterInterface
*/
public function format()
{
$swimlanes = $this->swimlaneModel->getSwimlanes($this->projectId);
$swimlanes = $this->swimlaneModel->getAllByStatus($this->projectId, SwimlaneModel::ACTIVE);
$columns = $this->columnModel->getAll($this->projectId);
if (empty($swimlanes) || empty($columns)) {

View File

@ -123,7 +123,7 @@ class TaskHelper extends Base
$attributes = array_merge(array('tabindex="5"'), $attributes);
$html = '';
if (! (count($swimlanes) === 1 && key($swimlanes) == 0)) {
if (count($swimlanes) > 1) {
$html .= $this->helper->form->label(t('Swimlane'), 'swimlane_id');
$html .= $this->helper->form->select('swimlane_id', $swimlanes, $values, $errors, $attributes);
}

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Ovaj izvoz sadržava broj zadataka po koloni grupisanih po danima.',
'Active swimlanes' => 'Aktivne swimline trake',
'Add a new swimlane' => 'Dodaj novu swimline traku',
'Change default swimlane' => 'Preimenuj podrazumijevanu swimline traku',
'Default swimlane' => 'Podrazumijevana swimline traka',
'Do you really want to remove this swimlane: "%s"?' => 'Da li zaista želiš ukloniti ovu swimline traku: "%s"?',
'Inactive swimlanes' => 'Neaktivne swimline trake',
'Remove a swimlane' => 'Ukloni swimline traku',
'Show default swimlane' => 'Prikaži podrazumijevanu swimline traku',
'Swimlane modification for the project "%s"' => 'Izmjene swimline trake za projekat "%s"',
'Swimlane removed successfully.' => 'Swimline traka uspješno uklonjena.',
'Swimlanes' => 'Swimline trake',
'Swimlane updated successfully.' => 'Swimline traka uspjeno ažurirana.',
'The default swimlane have been updated successfully.' => 'Podrazumijevana swimline traka uspješno ažurirana.',
'Unable to remove this swimlane.' => 'Nemoguće ukloniti swimline traku.',
'Unable to update this swimlane.' => 'Nemoguće ažurirati swimline traku.',
'Your swimlane have been created successfully.' => 'Swimline traka je uspješno kreirana.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Tento export obsahuje počet úkolů pro jednotlivé sloupce seskupených podle dní.',
'Active swimlanes' => 'Aktivní dráhy',
'Add a new swimlane' => 'Přidat novou dráhu',
'Change default swimlane' => 'Změnit výchozí dráhu',
'Default swimlane' => 'Výchozí dráha',
'Do you really want to remove this swimlane: "%s"?' => 'Opravdu si přejete odstranit tuto dráhu: "%s"?',
'Inactive swimlanes' => 'Neaktivní dráha',
'Remove a swimlane' => 'Odstranit dráhu',
'Show default swimlane' => 'Zobrazit výchozí dráhu',
'Swimlane modification for the project "%s"' => 'Změny dráhy pro projekt "%s"',
'Swimlane removed successfully.' => 'Dráha byla odstraněna.',
'Swimlanes' => 'Dráhy',
'Swimlane updated successfully.' => 'Dráha byla upravena.',
'The default swimlane have been updated successfully.' => 'Výchozí dráha byla upravena',
'Unable to remove this swimlane.' => 'Tuto dráhu nelze odstranit.',
'Unable to update this swimlane.' => 'Tuto dráhu nelze upravit.',
'Your swimlane have been created successfully.' => 'Dráha byla vytvořena.',

View File

@ -441,17 +441,14 @@ return array(
// 'This export contains the number of tasks per column grouped per day.' => '',
// 'Active swimlanes' => '',
// 'Add a new swimlane' => '',
// 'Change default swimlane' => '',
// 'Default swimlane' => '',
// 'Do you really want to remove this swimlane: "%s"?' => '',
// 'Inactive swimlanes' => '',
// 'Remove a swimlane' => '',
// 'Show default swimlane' => '',
// 'Swimlane modification for the project "%s"' => '',
// 'Swimlane removed successfully.' => '',
// 'Swimlanes' => '',
// 'Swimlane updated successfully.' => '',
// 'The default swimlane have been updated successfully.' => '',
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Dieser Export enthält die Anzahl der Aufgaben pro Spalte nach Tagen gruppiert.',
'Active swimlanes' => 'Aktive Swimlane',
'Add a new swimlane' => 'Eine neue Swimlane hinzufügen',
'Change default swimlane' => 'Standard-Swimlane ändern',
'Default swimlane' => 'Standard-Swimlane',
'Do you really want to remove this swimlane: "%s"?' => 'Diese Swimlane wirklich ändern: "%s"?',
'Inactive swimlanes' => 'Inaktive Swimlane',
'Remove a swimlane' => 'Swimlane entfernen',
'Show default swimlane' => 'Standard-Swimlane anzeigen',
'Swimlane modification for the project "%s"' => 'Swimlane-Änderung für das Projekt "%s"',
'Swimlane removed successfully.' => 'Swimlane erfolgreich entfernt.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane erfolgreich geändert.',
'The default swimlane have been updated successfully.' => 'Die Standard-Swimlane wurden erfolgreich aktualisiert. Die Standard-Swimlane wurden erfolgreich aktualisiert.',
'Unable to remove this swimlane.' => 'Es ist nicht möglich, die Swimlane zu entfernen.',
'Unable to update this swimlane.' => 'Es ist nicht möglich, die Swimlane zu ändern.',
'Your swimlane have been created successfully.' => 'Die Swimlane wurde erfolgreich angelegt.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Αυτή η κατάσταση περιέχει τον αριθμό των εργασιών ανά στήλη ομαδοποιημένα ανά ημέρα.',
'Active swimlanes' => 'Ενεργές λωρίδες',
'Add a new swimlane' => 'Προσθήκη λωρίδας',
'Change default swimlane' => 'Αλλαγή της εξ\' ορισμού λωρίδας',
'Default swimlane' => 'Εξ\' ορισμού λωρίδα',
'Do you really want to remove this swimlane: "%s"?' => 'Σίγουρα θέλετε να αφαιρέσετε τη λωρίδα : « %s » ?',
'Inactive swimlanes' => 'Ανενεργές Λωρίδες',
'Remove a swimlane' => 'Αφαίρεση λωρίδας',
'Show default swimlane' => 'Εμφάνιση προεπιλεγμένων λωρίδων',
'Swimlane modification for the project "%s"' => 'Τροποποίηση λωρίδας για το έργο « %s »',
'Swimlane removed successfully.' => 'Η λωρίδα αφαιρέθηκε με επιτυχία.',
'Swimlanes' => 'Λωρίδες',
'Swimlane updated successfully.' => 'Η λωρίδα ενημερώθηκε με επιτυχία.',
'The default swimlane have been updated successfully.' => 'Η προεπιλεγμένη λωρίδα ενημερώθηκε με επιτυχία.',
'Unable to remove this swimlane.' => 'Αδύνατο να αφαιρεθεί η λωρίδα.',
'Unable to update this swimlane.' => 'Αδύνατο να ενημερωθεί η λωρίδα.',
'Your swimlane have been created successfully.' => 'Η λωρίδα δημιουργήθηκε με επιτυχία.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Esta exportación contiene el número de tareas por columna agrupadas por día.',
'Active swimlanes' => 'Calles activas',
'Add a new swimlane' => 'Añadir nueva calle',
'Change default swimlane' => 'Cambiar la calle por defecto',
'Default swimlane' => 'Calle por defecto',
'Do you really want to remove this swimlane: "%s"?' => '¿Realmente desea eliminar esta calle: «%s»?',
'Inactive swimlanes' => 'Calles inactivas',
'Remove a swimlane' => 'Eliminar una calle',
'Show default swimlane' => 'Mostrar calle por defecto',
'Swimlane modification for the project "%s"' => 'Modificación de la calle para el proyecto «%s»',
'Swimlane removed successfully.' => 'Calle eliminada correctamente.',
'Swimlanes' => 'Calles',
'Swimlane updated successfully.' => 'Calle actualizada correctamente.',
'The default swimlane have been updated successfully.' => 'La calle por defecto ha sido actualizada correctamente.',
'Unable to remove this swimlane.' => 'No es posible eliminar esta calle.',
'Unable to update this swimlane.' => 'No es posible actualizar esta calle.',
'Your swimlane have been created successfully.' => 'Su calle ha sido creada correctamente.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Tämä tiedosto sisältää tehtäviä sarakkeisiin päiväkohtaisesti ryhmilteltyinä',
'Active swimlanes' => 'Aktiiviset kaistat',
'Add a new swimlane' => 'Lisää uusi kaista',
'Change default swimlane' => 'Vaihda oletuskaistaa',
'Default swimlane' => 'Oletuskaista',
'Do you really want to remove this swimlane: "%s"?' => 'Haluatko varmasti poistaa tämän kaistan: "%s"?',
'Inactive swimlanes' => 'Passiiviset kaistat',
'Remove a swimlane' => 'Poista kaista',
'Show default swimlane' => 'Näytä oletuskaista',
'Swimlane modification for the project "%s"' => 'Kaistamuutos projektille "%s"',
'Swimlane removed successfully.' => 'Kaista poistettu onnistuneesti.',
'Swimlanes' => 'Kaistat',
'Swimlane updated successfully.' => 'Kaista päivitetty onnistuneesti.',
'The default swimlane have been updated successfully.' => 'Oletuskaista päivitetty onnistuneesti.',
'Unable to remove this swimlane.' => 'Kaistan poisto epäonnistui.',
'Unable to update this swimlane.' => 'Kaistan päivittäminen epäonnistui.',
'Your swimlane have been created successfully.' => 'Kaista luotu onnistuneesti.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Cet export contient le nombre de tâches par colonne groupé par jour.',
'Active swimlanes' => 'Swimlanes actives',
'Add a new swimlane' => 'Ajouter une nouvelle swimlane',
'Change default swimlane' => 'Modifier la swimlane par défaut',
'Default swimlane' => 'Swimlane par défaut',
'Do you really want to remove this swimlane: "%s"?' => 'Voulez-vous vraiment supprimer cette swimlane : « %s » ?',
'Inactive swimlanes' => 'Swimlanes inactives',
'Remove a swimlane' => 'Supprimer une swimlane',
'Show default swimlane' => 'Afficher la swimlane par défaut',
'Swimlane modification for the project "%s"' => 'Modification d\'une swimlane pour le projet « %s »',
'Swimlane removed successfully.' => 'Swimlane supprimée avec succès.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane mise à jour avec succès.',
'The default swimlane have been updated successfully.' => 'La swimlane par défaut a été mise à jour avec succès.',
'Unable to remove this swimlane.' => 'Impossible de supprimer cette swimlane.',
'Unable to update this swimlane.' => 'Impossible de mettre à jour cette swimlane.',
'Your swimlane have been created successfully.' => 'Votre swimlane a été créée avec succès.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Ez az export tartalmazza a feladatok számát oszloponként összesítve, napokra lebontva.',
'Active swimlanes' => 'Aktív sávok',
'Add a new swimlane' => 'Új sáv',
'Change default swimlane' => 'Alapértelmezett sáv megváltoztatása',
'Default swimlane' => 'Alapértelmezett folyamat',
'Do you really want to remove this swimlane: "%s"?' => 'Valóban törölni akarja ezt a sávot: %s ?',
'Inactive swimlanes' => 'Inaktív sávok',
'Remove a swimlane' => 'Sáv törlés',
'Show default swimlane' => 'Alapértelmezett sáv megjelenítése',
'Swimlane modification for the project "%s"' => '%s projekt sávjainak módosítása',
'Swimlane removed successfully.' => 'Sáv sikeresen törölve.',
'Swimlanes' => 'Sávok',
'Swimlane updated successfully.' => 'Sáv sikeresen frissítve',
'The default swimlane have been updated successfully.' => 'Az alapértelmezett sáv sikeresen frissítve.',
'Unable to remove this swimlane.' => 'A sáv törlése sikertelen.',
'Unable to update this swimlane.' => 'A sáv frissítése sikertelen.',
'Your swimlane have been created successfully.' => 'A sáv sikeresen létrehozva.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom yang dikelompokan per hari.',
'Active swimlanes' => 'Swimlanes aktif',
'Add a new swimlane' => 'Tambah swimlane baru',
'Change default swimlane' => 'Ganti swimlane default',
'Default swimlane' => 'Swimlane default',
'Do you really want to remove this swimlane: "%s"?' => 'Apakah Anda yakin mau menghapus swimlane ini: "%s"?',
'Inactive swimlanes' => 'Swimlanes tidak aktif',
'Remove a swimlane' => 'Hapus swimlane',
'Show default swimlane' => 'Lihat swimlane default',
'Swimlane modification for the project "%s"' => 'Modifikasi swimlane untuk proyek "%s"',
'Swimlane removed successfully.' => 'Swimlane berhasil dihapus.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane berhasil diperbarui.',
'The default swimlane have been updated successfully.' => 'Swimlane default berhasil diperbarui.',
'Unable to remove this swimlane.' => 'Tidak dapat menghapus swimlane ini.',
'Unable to update this swimlane.' => 'Tidak dapat memperbarui swimlane ini.',
'Your swimlane have been created successfully.' => 'Swimlane Anda berhasil dibuat.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Questo export contiene il numero di task per colonna raggruppati per giorno',
'Active swimlanes' => 'Corsie attive',
'Add a new swimlane' => 'Aggiungi una corsia',
'Change default swimlane' => 'Cambia la corsia predefinita',
'Default swimlane' => 'Corsia predefinita',
'Do you really want to remove this swimlane: "%s"?' => 'Vuoi davvero rimuovere la seguente corsia: "%s"?',
'Inactive swimlanes' => 'Corsie inattive',
'Remove a swimlane' => 'Rimuovi una corsia',
'Show default swimlane' => 'Mostra la corsia predefinita',
'Swimlane modification for the project "%s"' => 'Modifica corsia per il progetto "%s"',
'Swimlane removed successfully.' => 'Corsia rimossa con successo.',
'Swimlanes' => 'Corsie',
'Swimlane updated successfully.' => 'Corsia aggiornata con successo.',
'The default swimlane have been updated successfully.' => 'La corsia predefinita è stata aggiornata con successo.',
'Unable to remove this swimlane.' => 'Impossibile rimuovere questa corsia.',
'Unable to update this swimlane.' => 'Impossibile aggiornare questa corsia.',
'Your swimlane have been created successfully.' => 'La tua corsia è stata creata con successo',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'この出力は日時のカラムごとのタスク数を集計したものです',
'Active swimlanes' => 'アクティブなスイムレーン',
'Add a new swimlane' => '新しいスイムレーン',
'Change default swimlane' => 'デフォルトスイムレーンの変更',
'Default swimlane' => 'デフォルトスイムレーン',
'Do you really want to remove this swimlane: "%s"?' => 'このスイムレーン「%s」を本当に削除しますか',
'Inactive swimlanes' => 'インタラクティブなスイムレーン',
'Remove a swimlane' => 'スイムレーンの削除',
'Show default swimlane' => 'デフォルトスイムレーンの表示',
'Swimlane modification for the project "%s"' => '「%s」に対するスイムレーン変更',
'Swimlane removed successfully.' => 'スイムレーンを削除しました。',
'Swimlanes' => 'スイムレーン',
'Swimlane updated successfully.' => 'スイムレーンを更新しました。',
'The default swimlane have been updated successfully.' => 'デフォルトスイムレーンを更新しました。',
'Unable to remove this swimlane.' => 'スイムレーンを削除できませんでした。',
'Unable to update this swimlane.' => 'スイムレーンを更新できませんでした。',
'Your swimlane have been created successfully.' => 'スイムレーンが作成されました。',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => '이 출력은 날짜의 칼람별 할일 수를 집계한 것입니다',
'Active swimlanes' => '액티브한 스윔레인',
'Add a new swimlane' => ' 새로운 스윔레인',
'Change default swimlane' => '기본 스윔레인의 변경',
'Default swimlane' => '기본 스윔레인',
'Do you really want to remove this swimlane: "%s"?' => '스웜레인을 삭제하시겠습니까: "%s"?',
'Inactive swimlanes' => '인터랙티브한 스윔레인',
'Remove a swimlane' => '스윔레인의 삭제',
'Show default swimlane' => '기본 스윔레인의 표시',
'Swimlane modification for the project "%s"' => '"%s" 프로젝트의 스웜레인 수정',
'Swimlane removed successfully.' => '스윔레인을 삭제했습니다.',
'Swimlanes' => '스윔레인',
'Swimlane updated successfully.' => '스윔레인을 갱신했습니다.',
'The default swimlane have been updated successfully.' => '기본 스윔레인을 갱신했습니다.',
'Unable to remove this swimlane.' => '스윔레인을 삭제할 수 없었습니다.',
'Unable to update this swimlane.' => '스윔레인을 갱신할 수 없었습니다.',
'Your swimlane have been created successfully.' => '스윔레인이 작성되었습니다.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom dikelompokan perhari.',
'Active swimlanes' => 'Swimlanes aktif',
'Add a new swimlane' => 'Tambah swimlane baharu',
'Change default swimlane' => 'Tukar piawai swimlane',
'Default swimlane' => 'Piawai swimlane',
'Do you really want to remove this swimlane: "%s"?' => 'Anda yakin untuk menghapus swimlane ini : « %s » ?',
'Inactive swimlanes' => 'Swimlanes tidak aktif',
'Remove a swimlane' => 'Padam swimlane',
'Show default swimlane' => 'Tampilkan piawai swimlane',
'Swimlane modification for the project "%s"' => 'Modifikasi swimlane untuk projek « %s »',
'Swimlane removed successfully.' => 'Swimlane telah dipadamkan.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane telah dikemaskini.',
'The default swimlane have been updated successfully.' => 'Standar swimlane berhasil diperbaharui.',
'Unable to remove this swimlane.' => 'Tidak dapat menghapus swimlane ini.',
'Unable to update this swimlane.' => 'Tidak dapat memperbaharui swimlane ini.',
'Your swimlane have been created successfully.' => 'Swimlane anda berhasil dibuat.',

View File

@ -441,17 +441,14 @@ return array(
// 'This export contains the number of tasks per column grouped per day.' => '',
'Active swimlanes' => 'Aktive svømmebaner',
'Add a new swimlane' => 'Legg til en ny svømmebane',
'Change default swimlane' => 'Endre standard svømmebane',
'Default swimlane' => 'Standard svømmebane',
// 'Do you really want to remove this swimlane: "%s"?' => '',
// 'Inactive swimlanes' => '',
'Remove a swimlane' => 'Fjern en svømmebane',
'Show default swimlane' => 'Vis standard svømmebane',
// 'Swimlane modification for the project "%s"' => '',
'Swimlane removed successfully.' => 'Svømmebane fjernet',
'Swimlanes' => 'Svømmebaner',
'Swimlane updated successfully.' => 'Svømmebane oppdatert',
// 'The default swimlane have been updated successfully.' => '',
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
// 'Your swimlane have been created successfully.' => '',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Dit rapport bevat het aantal taken per kolom gegroupeerd per dag.',
'Active swimlanes' => 'Actieve swinlanes',
'Add a new swimlane' => 'Nieuwe swimlane toevoegen',
'Change default swimlane' => 'Standaard swimlane aapassen',
'Default swimlane' => 'Standaard swinlane',
'Do you really want to remove this swimlane: "%s"?' => 'Weet u zeker dat u deze swimlane wil verwijderen : « %s » ?',
'Inactive swimlanes' => 'Inactieve swinlanes',
'Remove a swimlane' => 'Verwijder swinlane',
'Show default swimlane' => 'Standaard swimlane tonen',
'Swimlane modification for the project "%s"' => 'Swinlane aanpassing voor project « %s »',
'Swimlane removed successfully.' => 'Swimlane succesvol verwijderd.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane succesvol aangepast.',
'The default swimlane have been updated successfully.' => 'De standaard swimlane is succesvol aangepast.',
'Unable to remove this swimlane.' => 'Swimlane verwijderen niet gelukt.',
'Unable to update this swimlane.' => 'Swimlane aanpassen niet gelukt.',
'Your swimlane have been created successfully.' => 'Swimlane succesvol aangemaakt.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Ten eksport zawiera ilość zadań zgrupowanych w kolumnach na dzień',
'Active swimlanes' => 'Aktywne tory',
'Add a new swimlane' => 'Dodaj tor',
'Change default swimlane' => 'Zmień domyślny tor',
'Default swimlane' => 'Domyślny tor',
'Do you really want to remove this swimlane: "%s"?' => 'Czy na pewno chcesz usunąć tor: "%s"?',
'Inactive swimlanes' => 'Nieaktywne tory',
'Remove a swimlane' => 'Usuń tor',
'Show default swimlane' => 'Pokaż domyślny tor',
'Swimlane modification for the project "%s"' => 'Edycja torów dla projektu "%s"',
'Swimlane removed successfully.' => 'Tor usunięty pomyślnie.',
'Swimlanes' => 'Tory',
'Swimlane updated successfully.' => 'Zaktualizowano tor.',
'The default swimlane have been updated successfully.' => 'Domyślny tor zaktualizowany pomyślnie.',
'Unable to remove this swimlane.' => 'Nie można usunąć toru.',
'Unable to update this swimlane.' => 'Nie można zaktualizować toru.',
'Your swimlane have been created successfully.' => 'Tor utworzony pomyślnie.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Esta exportação contém o número de tarefas por coluna agrupada por dia.',
'Active swimlanes' => 'Ativar swimlanes',
'Add a new swimlane' => 'Adicionar swimlane',
'Change default swimlane' => 'Alterar swimlane padrão',
'Default swimlane' => 'Swimlane padrão',
'Do you really want to remove this swimlane: "%s"?' => 'Você realmente deseja remover esta swimlane: "%s"?',
'Inactive swimlanes' => 'Desativar swimlanes',
'Remove a swimlane' => 'Remover uma swimlane',
'Show default swimlane' => 'Exibir swimlane padrão',
'Swimlane modification for the project "%s"' => 'Modificação de swimlane para o projeto "%s"',
'Swimlane removed successfully.' => 'Swimlane removida com sucesso.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane atualizada com sucesso.',
'The default swimlane have been updated successfully.' => 'A swimlane padrão foi atualizada com sucesso.',
'Unable to remove this swimlane.' => 'Não foi possível remover esta swimlane.',
'Unable to update this swimlane.' => 'Não foi possível atualizar esta swimlane.',
'Your swimlane have been created successfully.' => 'Sua swimlane foi criada com sucesso.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Esta exportação contém o número de tarefas por coluna agrupada por dia.',
'Active swimlanes' => 'Activar swimlanes',
'Add a new swimlane' => 'Adicionar novo swimlane',
'Change default swimlane' => 'Alterar swimlane padrão',
'Default swimlane' => 'Swimlane padrão',
'Do you really want to remove this swimlane: "%s"?' => 'Tem a certeza que quer remover este swimlane: "%s"?',
'Inactive swimlanes' => 'Desactivar swimlanes',
'Remove a swimlane' => 'Remover um swimlane',
'Show default swimlane' => 'Mostrar swimlane padrão',
'Swimlane modification for the project "%s"' => 'Modificação de swimlane para o projeto "%s"',
'Swimlane removed successfully.' => 'Swimlane removido com sucesso.',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane atualizado com sucesso.',
'The default swimlane have been updated successfully.' => 'O swimlane padrão foi atualizado com sucesso.',
'Unable to remove this swimlane.' => 'Não foi possível remover este swimlane.',
'Unable to update this swimlane.' => 'Não foi possível atualizar este swimlane.',
'Your swimlane have been created successfully.' => 'Seu swimlane foi criado com sucesso.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Этот экспорт содержит ряд задач в колонках, сгруппированные по дням.',
'Active swimlanes' => 'Активные дорожки',
'Add a new swimlane' => 'Добавить новую дорожку',
'Change default swimlane' => 'Сменить стандартную дорожку',
'Default swimlane' => 'Стандартная дорожка',
'Do you really want to remove this swimlane: "%s"?' => 'Вы действительно хотите удалить дорожку "%s"?',
'Inactive swimlanes' => 'Неактивные дорожки',
'Remove a swimlane' => 'Удалить дорожку',
'Show default swimlane' => 'Показать стандартную дорожку',
'Swimlane modification for the project "%s"' => 'Редактирование дорожки для проекта "%s"',
'Swimlane removed successfully.' => 'Дорожка успешно удалена',
'Swimlanes' => 'Дорожки',
'Swimlane updated successfully.' => 'Дорожка успешно обновлена.',
'The default swimlane have been updated successfully.' => 'Стандартная swimlane был успешно обновлен.',
'Unable to remove this swimlane.' => 'Невозможно удалить дорожку.',
'Unable to update this swimlane.' => 'Невозможно обновить дорожку.',
'Your swimlane have been created successfully.' => 'Ваша дорожка была успешно создан.',

View File

@ -441,17 +441,14 @@ return array(
// 'This export contains the number of tasks per column grouped per day.' => '',
'Active swimlanes' => 'Aktivni razdelnik',
'Add a new swimlane' => 'Dodaj razdelnik',
'Change default swimlane' => 'Zameni osnovni razdelnik',
'Default swimlane' => 'Osnovni razdelnik',
'Do you really want to remove this swimlane: "%s"?' => 'Da li da uklonim razdelnik: "%s"?',
'Inactive swimlanes' => 'Neaktivni razdelniki',
'Remove a swimlane' => 'Ukloni razdelnik',
'Show default swimlane' => 'Prikaži osnovni razdelnik',
'Swimlane modification for the project "%s"' => 'Izmena razdelnika za projekat "%s"',
'Swimlane removed successfully.' => 'Razdelnik uspešno uklonjen.',
'Swimlanes' => 'Razdelnici',
'Swimlane updated successfully.' => 'Razdelnik zaktualizowany pomyślnie.',
// 'The default swimlane have been updated successfully.' => '',
// 'Unable to remove this swimlane.' => '',
// 'Unable to update this swimlane.' => '',
'Your swimlane have been created successfully.' => 'Razdelnik je uspešno kreiran.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Denna export innehåller antalet uppgifter per kolumn grupperade per dag.',
'Active swimlanes' => 'Aktiva swimlanes',
'Add a new swimlane' => 'Lägg till en nytt swimlane',
'Change default swimlane' => 'Ändra standard swimlane',
'Default swimlane' => 'Standard swimlane',
'Do you really want to remove this swimlane: "%s"?' => 'Vill du verkligen ta bort denna swimlane: "%s"?',
'Inactive swimlanes' => 'Inaktiv swimlane',
'Remove a swimlane' => 'Ta bort en swimlane',
'Show default swimlane' => 'Visa standard swimlane',
'Swimlane modification for the project "%s"' => 'Ändra swimlane för projektet "%s"',
'Swimlane removed successfully.' => 'Swimlane togs bort',
'Swimlanes' => 'Swimlanes',
'Swimlane updated successfully.' => 'Swimlane uppdaterad',
'The default swimlane have been updated successfully.' => 'Standardswimlane har uppdaterats',
'Unable to remove this swimlane.' => 'Kunde inte ta bort swimlane',
'Unable to update this swimlane.' => 'Kunde inte uppdatera swimlane',
'Your swimlane have been created successfully.' => 'Din swimlane har skapats',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'การส่งออกนี้เป็นการนับจำนวนงานในแต่ละคอลัมน์ในแต่ละวัน',
'Active swimlanes' => 'สวิมเลนพร้อมใช้งาน',
'Add a new swimlane' => 'เพิ่มสวิมเลนใหม่',
'Change default swimlane' => 'เปลี่ยนสวิมเลนเริ่มต้น',
'Default swimlane' => 'สวิมเลนเริ่มต้น',
'Do you really want to remove this swimlane: "%s"?' => 'คุณต้องการลบสวิมเลนนี้ : "%s"?',
'Inactive swimlanes' => 'สวิมเลนไม่ทำงาน',
'Remove a swimlane' => 'ลบสวิมเลน',
'Show default swimlane' => 'แสดงสวิมเลนเริ่มต้น',
'Swimlane modification for the project "%s"' => 'แก้ไขสวิมเลนสำหรับโปรเจค "%s"',
'Swimlane removed successfully.' => 'ลบสวิมเลนเรียบร้อยแล้ว',
'Swimlanes' => 'สวิมเลน',
'Swimlane updated successfully.' => 'ปรับปรุงสวิมเลนเรียบร้อยแล้ว',
'The default swimlane have been updated successfully.' => 'สวิมเลนเริ่มต้นปรับปรุงเรียบร้อยแล้ว',
'Unable to remove this swimlane.' => 'ไม่สามารถลบสวิมเลนนี้',
'Unable to update this swimlane.' => 'ไม่สามารถปรับปรุงสวิมเลนนี้',
'Your swimlane have been created successfully.' => 'สวิมเลนของคุณถูกสร้างเรียบร้อยแล้ว',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => 'Bu dışa aktarım günlük gruplanmış olarak her sütundaki görev sayısını içerir.',
'Active swimlanes' => 'Aktif Kulvar',
'Add a new swimlane' => 'Yeni bir Kulvar ekle',
'Change default swimlane' => 'Varsayılan Kulvarı değiştir',
'Default swimlane' => 'Varsayılan Kulvar',
'Do you really want to remove this swimlane: "%s"?' => 'Bu Kulvarı silmek istediğinize emin misiniz?: "%s"?',
'Inactive swimlanes' => 'Pasif Kulvarlar',
'Remove a swimlane' => 'Kulvarı sil',
'Show default swimlane' => 'Varsayılan Kulvarı göster',
'Swimlane modification for the project "%s"' => '"%s" Projesi için Kulvar değişikliği',
'Swimlane removed successfully.' => 'Kulvar başarıyla kaldırıldı.',
'Swimlanes' => 'Kulvarlar',
'Swimlane updated successfully.' => 'Kulvar başarıyla güncellendi.',
'The default swimlane have been updated successfully.' => 'Varsayılan Kulvarlar başarıyla güncellendi.',
'Unable to remove this swimlane.' => 'Bu Kulvarı silmek mümkün değil.',
'Unable to update this swimlane.' => 'Bu Kulvarı değiştirmek mümkün değil.',
'Your swimlane have been created successfully.' => 'Kulvar başarıyla oluşturuldu.',

View File

@ -441,17 +441,14 @@ return array(
'This export contains the number of tasks per column grouped per day.' => '此导出包含每列的任务数,按天分组',
'Active swimlanes' => '活动里程碑',
'Add a new swimlane' => '添加新里程碑',
'Change default swimlane' => '修改默认里程碑',
'Default swimlane' => '默认里程碑',
'Do you really want to remove this swimlane: "%s"?' => '确定要删除里程碑:"%s"?',
'Inactive swimlanes' => '非活动里程碑',
'Remove a swimlane' => '删除里程碑',
'Show default swimlane' => '显示默认里程碑',
'Swimlane modification for the project "%s"' => '项目"%s"的里程碑变更',
'Swimlane removed successfully.' => '成功删除里程碑',
'Swimlanes' => '里程碑',
'Swimlane updated successfully.' => '成功更新了里程碑。',
'The default swimlane have been updated successfully.' => '成功更新了默认里程碑。',
'Unable to remove this swimlane.' => '无法删除此里程碑',
'Unable to update this swimlane.' => '无法更新此里程碑',
'Your swimlane have been created successfully.' => '已经成功创建里程碑。',

View File

@ -26,7 +26,6 @@ class ProjectDuplicationModel extends Base
'categoryModel',
'projectPermissionModel',
'actionModel',
'swimlaneModel',
'tagDuplicationModel',
'projectMetadataModel',
'projectTaskDuplicationModel',
@ -42,6 +41,7 @@ class ProjectDuplicationModel extends Base
public function getPossibleSelection()
{
return array(
'swimlaneModel',
'boardModel',
'categoryModel',
'projectPermissionModel',
@ -94,7 +94,7 @@ class ProjectDuplicationModel extends Base
return false;
}
// Clone Columns, Categories, Permissions and Actions
// Clone Swimlanes, Columns, Categories, Permissions and Actions
foreach ($this->getPossibleSelection() as $model) {
// Skip if optional part has not been selected
@ -151,11 +151,7 @@ class ProjectDuplicationModel extends Base
'priority_end' => $project['priority_end'],
);
if (! $this->db->table(ProjectModel::TABLE)->save($values)) {
return false;
}
return $this->db->getLastId();
return $this->db->table(ProjectModel::TABLE)->persist($values);
}
/**

View File

@ -322,18 +322,18 @@ class ProjectModel extends Base
*
* @access public
* @param array $values Form values
* @param integer $user_id User who create the project
* @param bool $add_user Automatically add the user
* @return integer Project id
* @param integer $userId User who create the project
* @param bool $addUser Automatically add the user
* @return int Project id
*/
public function create(array $values, $user_id = 0, $add_user = false)
public function create(array $values, $userId = 0, $addUser = false)
{
$this->db->startTransaction();
$values['token'] = '';
$values['last_modified'] = time();
$values['is_private'] = empty($values['is_private']) ? 0 : 1;
$values['owner_id'] = $user_id;
$values['owner_id'] = $userId;
if (! empty($values['identifier'])) {
$values['identifier'] = strtoupper($values['identifier']);
@ -353,8 +353,13 @@ class ProjectModel extends Base
return false;
}
if ($add_user && $user_id) {
$this->projectUserRoleModel->addUser($project_id, $user_id, Role::PROJECT_MANAGER);
if (! $this->swimlaneModel->create($project_id, t('Default swimlane'))) {
$this->db->cancelTransaction();
return false;
}
if ($addUser && $userId) {
$this->projectUserRoleModel->addUser($project_id, $userId, Role::PROJECT_MANAGER);
}
$this->categoryModel->createDefaultCategories($project_id);

View File

@ -37,38 +37,40 @@ class SwimlaneModel extends Base
* Get a swimlane by the id
*
* @access public
* @param integer $swimlane_id Swimlane id
* @param integer $swimlaneId
* @return array
*/
public function getById($swimlane_id)
public function getById($swimlaneId)
{
return $this->db->table(self::TABLE)->eq('id', $swimlane_id)->findOne();
return $this->db->table(self::TABLE)->eq('id', $swimlaneId)->findOne();
}
/**
* Get the swimlane name by the id
*
* @access public
* @param integer $swimlane_id Swimlane id
* @param integer $swimlaneId
* @return string
*/
public function getNameById($swimlane_id)
public function getNameById($swimlaneId)
{
return $this->db->table(self::TABLE)->eq('id', $swimlane_id)->findOneColumn('name') ?: '';
return $this->db->table(self::TABLE)
->eq('id', $swimlaneId)
->findOneColumn('name');
}
/**
* Get a swimlane id by the project and the name
*
* @access public
* @param integer $project_id Project id
* @param integer $projectId Project id
* @param string $name Name
* @return integer
*/
public function getIdByName($project_id, $name)
public function getIdByName($projectId, $name)
{
return (int) $this->db->table(self::TABLE)
->eq('project_id', $project_id)
->eq('project_id', $projectId)
->eq('name', $name)
->findOneColumn('id');
}
@ -77,14 +79,14 @@ class SwimlaneModel extends Base
* Get a swimlane by the project and the name
*
* @access public
* @param integer $project_id Project id
* @param integer $projectId Project id
* @param string $name Swimlane name
* @return array
*/
public function getByName($project_id, $name)
public function getByName($projectId, $name)
{
return $this->db->table(self::TABLE)
->eq('project_id', $project_id)
->eq('project_id', $projectId)
->eq('name', $name)
->findOne();
}
@ -93,54 +95,46 @@ class SwimlaneModel extends Base
* Get first active swimlane for a project
*
* @access public
* @param integer $project_id
* @param integer $projectId
* @return array|null
*/
public function getFirstActiveSwimlane($project_id)
public function getFirstActiveSwimlane($projectId)
{
$swimlanes = $this->getSwimlanes($project_id);
if (empty($swimlanes)) {
return null;
}
return $swimlanes[0];
return $this->db->table(self::TABLE)
->eq('project_id', $projectId)
->eq('is_active', 1)
->asc('position')
->findOne();
}
/**
* Get default swimlane properties
* Get first active swimlaneId
*
* @access public
* @param integer $project_id Project id
* @return array
* @param int $projectId
* @return int
*/
public function getDefault($project_id)
public function getFirstActiveSwimlaneId($projectId)
{
$result = $this->db
->table(ProjectModel::TABLE)
->eq('id', $project_id)
->columns('id', 'default_swimlane', 'show_default_swimlane')
->findOne();
if ($result['default_swimlane'] === 'Default swimlane') {
$result['default_swimlane'] = t($result['default_swimlane']);
}
return $result;
return (int) $this->db->table(self::TABLE)
->eq('project_id', $projectId)
->eq('is_active', 1)
->asc('position')
->findOneColumn('id');
}
/**
* Get all swimlanes for a given project
*
* @access public
* @param integer $project_id Project id
* @param integer $projectId
* @return array
*/
public function getAll($project_id)
public function getAll($projectId)
{
return $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->eq('project_id', $projectId)
->orderBy('position', 'asc')
->findAll();
}
@ -149,15 +143,15 @@ class SwimlaneModel extends Base
* Get the list of swimlanes by status
*
* @access public
* @param integer $project_id Project id
* @param integer $status Status
* @param integer $projectId
* @param integer $status
* @return array
*/
public function getAllByStatus($project_id, $status = self::ACTIVE)
public function getAllByStatus($projectId, $status = self::ACTIVE)
{
$query = $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->eq('project_id', $projectId)
->eq('is_active', $status);
if ($status == self::ACTIVE) {
@ -169,66 +163,27 @@ class SwimlaneModel extends Base
return $query->findAll();
}
/**
* Get active swimlanes
*
* @access public
* @param integer $project_id Project id
* @return array
*/
public function getSwimlanes($project_id)
{
$swimlanes = $this->db
->table(self::TABLE)
->columns('id', 'name', 'description')
->eq('project_id', $project_id)
->eq('is_active', self::ACTIVE)
->orderBy('position', 'asc')
->findAll();
$defaultSwimlane = $this->db
->table(ProjectModel::TABLE)
->eq('id', $project_id)
->eq('show_default_swimlane', 1)
->findOneColumn('default_swimlane');
if ($defaultSwimlane) {
if ($defaultSwimlane === 'Default swimlane') {
$defaultSwimlane = t($defaultSwimlane);
}
array_unshift($swimlanes, array('id' => 0, 'name' => $defaultSwimlane));
}
return $swimlanes;
}
/**
* Get list of all swimlanes
*
* @access public
* @param integer $project_id Project id
* @param integer $projectId Project id
* @param boolean $prepend Prepend default value
* @param boolean $only_active Return only active swimlanes
* @param boolean $onlyActive Return only active swimlanes
* @return array
*/
public function getList($project_id, $prepend = false, $only_active = false)
public function getList($projectId, $prepend = false, $onlyActive = false)
{
$swimlanes = array();
$default = $this->db->table(ProjectModel::TABLE)->eq('id', $project_id)->eq('show_default_swimlane', 1)->findOneColumn('default_swimlane');
if ($prepend) {
$swimlanes[-1] = t('All swimlanes');
}
if (! empty($default)) {
$swimlanes[0] = $default === 'Default swimlane' ? t($default) : $default;
}
return $swimlanes + $this->db
->hashtable(self::TABLE)
->eq('project_id', $project_id)
->in('is_active', $only_active ? array(self::ACTIVE) : array(self::ACTIVE, self::INACTIVE))
->eq('project_id', $projectId)
->in('is_active', $onlyActive ? array(self::ACTIVE) : array(self::ACTIVE, self::INACTIVE))
->orderBy('position', 'asc')
->getAll('id', 'name');
}
@ -237,17 +192,24 @@ class SwimlaneModel extends Base
* Add a new swimlane
*
* @access public
* @param array $values Form values
* @return integer|boolean
* @param int $projectId
* @param string $name
* @param string $description
* @return bool|int
*/
public function create($values)
public function create($projectId, $name, $description = '')
{
if (! $this->projectModel->exists($values['project_id'])) {
if (! $this->projectModel->exists($projectId)) {
return 0;
}
$values['position'] = $this->getLastPosition($values['project_id']);
return $this->db->table(self::TABLE)->persist($values);
return $this->db->table(self::TABLE)->persist(array(
'project_id' => $projectId,
'name' => $name,
'description' => $description,
'position' => $this->getLastPosition($projectId),
'is_active' => 1,
));
}
/**
@ -265,70 +227,18 @@ class SwimlaneModel extends Base
->update($values);
}
/**
* Update the default swimlane
*
* @access public
* @param array $values Form values
* @return bool
*/
public function updateDefault(array $values)
{
return $this->db
->table(ProjectModel::TABLE)
->eq('id', $values['id'])
->update(array(
'default_swimlane' => $values['default_swimlane'],
'show_default_swimlane' => $values['show_default_swimlane'],
));
}
/**
* Enable the default swimlane
*
* @access public
* @param integer $project_id
* @return bool
*/
public function enableDefault($project_id)
{
return $this->db
->table(ProjectModel::TABLE)
->eq('id', $project_id)
->update(array(
'show_default_swimlane' => 1,
));
}
/**
* Disable the default swimlane
*
* @access public
* @param integer $project_id
* @return bool
*/
public function disableDefault($project_id)
{
return $this->db
->table(ProjectModel::TABLE)
->eq('id', $project_id)
->update(array(
'show_default_swimlane' => 0,
));
}
/**
* Get the last position of a swimlane
*
* @access public
* @param integer $project_id
* @param integer $projectId
* @return integer
*/
public function getLastPosition($project_id)
public function getLastPosition($projectId)
{
return $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->eq('project_id', $projectId)
->eq('is_active', 1)
->count() + 1;
}
@ -337,23 +247,23 @@ class SwimlaneModel extends Base
* Disable a swimlane
*
* @access public
* @param integer $project_id Project id
* @param integer $swimlane_id Swimlane id
* @param integer $projectId
* @param integer $swimlaneId
* @return bool
*/
public function disable($project_id, $swimlane_id)
public function disable($projectId, $swimlaneId)
{
$result = $this->db
->table(self::TABLE)
->eq('id', $swimlane_id)
->eq('id', $swimlaneId)
->eq('project_id', $projectId)
->update(array(
'is_active' => self::INACTIVE,
'position' => 0,
));
if ($result) {
// Re-order positions
$this->updatePositions($project_id);
$this->updatePositions($projectId);
}
return $result;
@ -363,18 +273,19 @@ class SwimlaneModel extends Base
* Enable a swimlane
*
* @access public
* @param integer $project_id Project id
* @param integer $swimlane_id Swimlane id
* @param integer $projectId
* @param integer $swimlaneId
* @return bool
*/
public function enable($project_id, $swimlane_id)
public function enable($projectId, $swimlaneId)
{
return $this->db
->table(self::TABLE)
->eq('id', $swimlane_id)
->eq('id', $swimlaneId)
->eq('project_id', $projectId)
->update(array(
'is_active' => self::ACTIVE,
'position' => $this->getLastPosition($project_id),
'position' => $this->getLastPosition($projectId),
));
}
@ -382,25 +293,25 @@ class SwimlaneModel extends Base
* Remove a swimlane
*
* @access public
* @param integer $project_id Project id
* @param integer $swimlane_id Swimlane id
* @param integer $projecId
* @param integer $swimlaneId
* @return bool
*/
public function remove($project_id, $swimlane_id)
public function remove($projecId, $swimlaneId)
{
$this->db->startTransaction();
// Tasks should not be assigned anymore to this swimlane
$this->db->table(TaskModel::TABLE)->eq('swimlane_id', $swimlane_id)->update(array('swimlane_id' => 0));
if (! $this->db->table(self::TABLE)->eq('id', $swimlane_id)->remove()) {
if ($this->db->table(TaskModel::TABLE)->eq('swimlane_id', $swimlaneId)->exists()) {
$this->db->cancelTransaction();
return false;
}
// Re-order positions
$this->updatePositions($project_id);
if (! $this->db->table(self::TABLE)->eq('id', $swimlaneId)->remove()) {
$this->db->cancelTransaction();
return false;
}
$this->updatePositions($projecId);
$this->db->closeTransaction();
return true;
@ -410,15 +321,15 @@ class SwimlaneModel extends Base
* Update swimlane positions after disabling or removing a swimlane
*
* @access public
* @param integer $project_id Project id
* @param integer $projectId
* @return boolean
*/
public function updatePositions($project_id)
public function updatePositions($projectId)
{
$position = 0;
$swimlanes = $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->eq('project_id', $projectId)
->eq('is_active', 1)
->asc('position')
->asc('id')
@ -441,37 +352,37 @@ class SwimlaneModel extends Base
* Change swimlane position
*
* @access public
* @param integer $project_id
* @param integer $swimlane_id
* @param integer $projectId
* @param integer $swimlaneId
* @param integer $position
* @return boolean
*/
public function changePosition($project_id, $swimlane_id, $position)
public function changePosition($projectId, $swimlaneId, $position)
{
if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('project_id', $project_id)->count()) {
if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('project_id', $projectId)->count()) {
return false;
}
$swimlane_ids = $this->db->table(self::TABLE)
$swimlaneIds = $this->db->table(self::TABLE)
->eq('is_active', 1)
->eq('project_id', $project_id)
->neq('id', $swimlane_id)
->eq('project_id', $projectId)
->neq('id', $swimlaneId)
->asc('position')
->findAllByColumn('id');
$offset = 1;
$results = array();
foreach ($swimlane_ids as $current_swimlane_id) {
foreach ($swimlaneIds as $currentSwimlaneId) {
if ($offset == $position) {
$offset++;
}
$results[] = $this->db->table(self::TABLE)->eq('id', $current_swimlane_id)->update(array('position' => $offset));
$results[] = $this->db->table(self::TABLE)->eq('id', $currentSwimlaneId)->update(array('position' => $offset));
$offset++;
}
$results[] = $this->db->table(self::TABLE)->eq('id', $swimlane_id)->update(array('position' => $position));
$results[] = $this->db->table(self::TABLE)->eq('id', $swimlaneId)->update(array('position' => $position));
return !in_array(false, $results, true);
}
@ -480,28 +391,29 @@ class SwimlaneModel extends Base
* Duplicate Swimlane to project
*
* @access public
* @param integer $project_from Project Template
* @param integer $project_to Project that receives the copy
* @return integer|boolean
* @param integer $projectSrcId
* @param integer $projectDstId
* @return boolean
*/
public function duplicate($project_from, $project_to)
public function duplicate($projectSrcId, $projectDstId)
{
$swimlanes = $this->getAll($project_from);
$swimlanes = $this->getAll($projectSrcId);
foreach ($swimlanes as $swimlane) {
unset($swimlane['id']);
$swimlane['project_id'] = $project_to;
if (! $this->db->table(self::TABLE)->eq('project_id', $projectDstId)->eq('name', $swimlane['name'])->exists()) {
$values = array(
'name' => $swimlane['name'],
'description' => $swimlane['description'],
'position' => $swimlane['position'],
'is_active' => $swimlane['is_active'],
'project_id' => $projectDstId,
);
if (! $this->db->table(self::TABLE)->save($swimlane)) {
if (! $this->db->table(self::TABLE)->persist($values)) {
return false;
}
}
$default_swimlane = $this->getDefault($project_from);
$default_swimlane['id'] = $project_to;
$this->updateDefault($default_swimlane);
}
return true;
}

View File

@ -62,7 +62,7 @@ class TaskCreationModel extends Base
$values = $this->dateParser->convert($values, array('date_started'), true);
$this->helper->model->removeFields($values, array('another_task', 'duplicate_multiple_projects'));
$this->helper->model->resetFields($values, array('creator_id', 'owner_id', 'swimlane_id', 'date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent'));
$this->helper->model->resetFields($values, array('creator_id', 'owner_id', 'date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent'));
if (empty($values['column_id'])) {
$values['column_id'] = $this->columnModel->getFirstColumnId($values['project_id']);
@ -80,7 +80,7 @@ class TaskCreationModel extends Base
$values['creator_id'] = $this->userSession->getId();
}
$values['swimlane_id'] = empty($values['swimlane_id']) ? 0 : $values['swimlane_id'];
$values['swimlane_id'] = empty($values['swimlane_id']) ? $this->swimlaneModel->getFirstActiveSwimlaneId($values['project_id']) : $values['swimlane_id'];
$values['date_creation'] = time();
$values['date_modification'] = $values['date_creation'];
$values['date_moved'] = $values['date_creation'];

View File

@ -79,11 +79,13 @@ class TaskDuplicationModel extends Base
}
// Check if the swimlane exists for the destination project
if ($values['swimlane_id'] > 0) {
$values['swimlane_id'] = $this->swimlaneModel->getIdByName(
$values['project_id'],
$this->swimlaneModel->getNameById($values['swimlane_id'])
);
if ($values['swimlane_id'] == 0) {
$values['swimlane_id'] = $this->swimlaneModel->getFirstActiveSwimlaneId($values['project_id']);
}
// Check if the column exists for the destination project

View File

@ -142,7 +142,6 @@ class TaskFinderModel extends Base
ColumnModel::TABLE.'.title AS column_name',
ColumnModel::TABLE.'.position AS column_position',
SwimlaneModel::TABLE.'.name AS swimlane_name',
ProjectModel::TABLE.'.default_swimlane',
ProjectModel::TABLE.'.name AS project_name'
)
->join(UserModel::TABLE, 'id', 'owner_id', TaskModel::TABLE)
@ -304,15 +303,13 @@ class TaskFinderModel extends Base
CategoryModel::TABLE.'.name AS category_name',
SwimlaneModel::TABLE.'.name AS swimlane_name',
ProjectModel::TABLE.'.name AS project_name',
ProjectModel::TABLE.'.default_swimlane',
ColumnModel::TABLE.'.title AS column_title',
UserModel::TABLE.'.username AS assignee_username',
UserModel::TABLE.'.name AS assignee_name',
'uc.username AS creator_username',
'uc.name AS creator_name',
CategoryModel::TABLE.'.description AS category_description',
ColumnModel::TABLE.'.position AS column_position',
ProjectModel::TABLE.'.default_swimlane'
ColumnModel::TABLE.'.position AS column_position'
)
->join(UserModel::TABLE, 'id', 'owner_id', TaskModel::TABLE)
->left(UserModel::TABLE, 'uc', 'id', TaskModel::TABLE, 'creator_id')

View File

@ -33,6 +33,10 @@ class TaskPositionModel extends Base
$task = $this->taskFinderModel->getById($task_id);
if ($swimlane_id == 0) {
$swimlane_id = $task['swimlane_id'];
}
if ($onlyOpen && $task['is_active'] == TaskModel::STATUS_CLOSED) {
return true;
}

View File

@ -139,6 +139,6 @@ class TaskStatusModel extends Base
->table(TaskModel::TABLE)
->eq('id', $task_id)
->eq('is_active', $status)
->count() === 1;
->exists();
}
}

63
app/Schema/Migration.php Normal file
View File

@ -0,0 +1,63 @@
<?php
namespace Schema;
use PDO;
function migrate_default_swimlane(PDO $pdo)
{
$projects = get_all_projects($pdo);
foreach ($projects as $project) {
// Create new default swimlane
$rq = $pdo->prepare('INSERT INTO swimlanes (project_id, name, is_active, position) VALUES (?, ?, ?, ?)');
$rq->execute(array(
$project['id'],
$project['default_swimlane'],
(int) $project['show_default_swimlane'],
$project['show_default_swimlane'] == 1 ? 1 : 0,
));
$swimlaneId = get_last_insert_id($pdo);
// Reorder swimlanes if the default one was active
if ($project['show_default_swimlane']) {
$rq = $pdo->prepare("UPDATE swimlanes SET position=position+1 WHERE project_id=? AND is_active='1' AND id!=?");
$rq->execute(array(
$project['id'],
$swimlaneId,
));
}
// Move all tasks to new swimlane
$rq = $pdo->prepare("UPDATE tasks SET swimlane_id=? WHERE swimlane_id='0' AND project_id=?");
$rq->execute(array(
$swimlaneId,
$project['id'],
));
// Migrate automatic actions
$rq = $pdo->prepare("UPDATE action_has_params SET value=? WHERE id IN (SELECT action_has_params.id FROM action_has_params LEFT JOIN actions ON actions.id=action_has_params.action_id WHERE project_id=? AND name='swimlane_id' AND value='0')");
$rq->execute(array($swimlaneId, $project['id']));
}
}
function get_all_projects(PDO $pdo)
{
$rq = $pdo->prepare('SELECT * FROM projects');
$rq->execute();
return $rq->fetchAll(PDO::FETCH_ASSOC);
}
function get_last_insert_id(PDO $pdo)
{
if (DB_DRIVER === 'postgres') {
$rq = $pdo->prepare('SELECT LASTVAL()');
$rq->execute();
return $rq->fetchColumn();
}
return $pdo->lastInsertId();
}

View File

@ -2,11 +2,23 @@
namespace Schema;
require_once __DIR__.'/Migration.php';
use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
const VERSION = 121;
const VERSION = 122;
function version_122(PDO $pdo)
{
migrate_default_swimlane($pdo);
$pdo->exec('ALTER TABLE `projects` DROP COLUMN `default_swimlane`');
$pdo->exec('ALTER TABLE `projects` DROP COLUMN `show_default_swimlane`');
$pdo->exec('ALTER TABLE `tasks` MODIFY `swimlane_id` INT(11) NOT NULL;');
$pdo->exec('ALTER TABLE tasks ADD CONSTRAINT tasks_swimlane_ibfk_1 FOREIGN KEY (swimlane_id) REFERENCES swimlanes(id) ON DELETE CASCADE');
}
function version_121(PDO $pdo)
{

View File

@ -2,11 +2,24 @@
namespace Schema;
require_once __DIR__.'/Migration.php';
use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
const VERSION = 100;
const VERSION = 101;
function version_101(PDO $pdo)
{
migrate_default_swimlane($pdo);
$pdo->exec('ALTER TABLE "projects" DROP COLUMN "default_swimlane"');
$pdo->exec('ALTER TABLE "projects" DROP COLUMN "show_default_swimlane"');
$pdo->exec('ALTER TABLE "tasks" ALTER COLUMN "swimlane_id" SET NOT NULL');
$pdo->exec('ALTER TABLE "tasks" ALTER COLUMN "swimlane_id" DROP DEFAULT');
$pdo->exec('ALTER TABLE "tasks" ADD FOREIGN KEY (swimlane_id) REFERENCES swimlanes ON DELETE CASCADE');
}
function version_100(PDO $pdo)
{

View File

@ -2,11 +2,18 @@
namespace Schema;
require_once __DIR__.'/Migration.php';
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
use PDO;
const VERSION = 111;
const VERSION = 112;
function version_112(PDO $pdo)
{
migrate_default_swimlane($pdo);
}
function version_111(PDO $pdo)
{

View File

@ -25,7 +25,6 @@
<?= $this->form->checkbox('categoryModel', t('Categories'), 1, true) ?>
<?= $this->form->checkbox('tagDuplicationModel', t('Tags'), 1, true) ?>
<?= $this->form->checkbox('actionModel', t('Actions'), 1, true) ?>
<?= $this->form->checkbox('swimlaneModel', t('Swimlanes'), 1, true) ?>
<?= $this->form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?>
</div>

View File

@ -17,7 +17,6 @@
<?= $this->form->checkbox('categoryModel', t('Categories'), 1, true) ?>
<?= $this->form->checkbox('tagDuplicationModel', t('Tags'), 1, true) ?>
<?= $this->form->checkbox('actionModel', t('Actions'), 1, true) ?>
<?= $this->form->checkbox('swimlaneModel', t('Swimlanes'), 1, false) ?>
<?= $this->form->checkbox('projectMetadataModel', t('Metadata'), 1, false) ?>
<?= $this->form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?>

View File

@ -19,7 +19,7 @@
<?= $this->url->link('#'.$this->text->e($task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
</td>
<td>
<?= $this->text->e($task['swimlane_name'] ?: $task['default_swimlane']) ?>
<?= $this->text->e($task['swimlane_name']) ?>
</td>
<td>
<?= $this->text->e($task['column_name']) ?>

View File

@ -1,14 +0,0 @@
<div class="page-header">
<h2><?= t('Change default swimlane') ?></h2>
</div>
<form method="post" action="<?= $this->url->href('SwimlaneController', 'updateDefault', array('project_id' => $project['id'])) ?>" autocomplete="off">
<?= $this->form->csrf() ?>
<?= $this->form->hidden('id', $values) ?>
<?= $this->form->label(t('Name'), 'default_swimlane') ?>
<?= $this->form->text('default_swimlane', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
<?= $this->form->checkbox('show_default_swimlane', t('Show default swimlane'), 1, $values['show_default_swimlane'] == 1) ?>
<?= $this->modal->submitButtons() ?>
</form>

View File

@ -7,21 +7,22 @@
</ul>
</div>
<?php if (! empty($active_swimlanes) || $default_swimlane['show_default_swimlane'] == 1): ?>
<h3><?= t('Active swimlanes') ?></h3>
<?php if (empty($active_swimlanes)): ?>
<p class="alert alert-error"><?= t('Your project must have at least one active swimlane.') ?></p>
<?php else: ?>
<?= $this->render('swimlane/table', array(
'swimlanes' => $active_swimlanes,
'project' => $project,
'default_swimlane' => $default_swimlane['show_default_swimlane'] == 1 ? $default_swimlane : array()
)) ?>
<?php endif ?>
<?php if (! empty($inactive_swimlanes) || $default_swimlane['show_default_swimlane'] == 0): ?>
<?php if (! empty($inactive_swimlanes)): ?>
<h3><?= t('Inactive swimlanes') ?></h3>
<?= $this->render('swimlane/table', array(
'swimlanes' => $inactive_swimlanes,
'project' => $project,
'default_swimlane' => $default_swimlane['show_default_swimlane'] == 0 ? $default_swimlane : array(),
'disable_handler' => true
'disable_handler' => true,
)) ?>
<?php endif ?>

View File

@ -6,33 +6,6 @@
<th><?= t('Name') ?></th>
<th class="column-8"><?= t('Actions') ?></th>
</tr>
<?php if (! empty($default_swimlane)): ?>
<tr>
<td>
<?= $this->text->e($default_swimlane['default_swimlane']) ?>
<?php if ($default_swimlane['default_swimlane'] !== t('Default swimlane')): ?>
&nbsp;(<?= t('Default swimlane') ?>)
<?php endif ?>
</td>
<td>
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a>
<ul>
<li>
<?= $this->modal->medium('edit', t('Edit'), 'SwimlaneController', 'editDefault', array('project_id' => $project['id'])) ?>
</li>
<li>
<?php if ($default_swimlane['show_default_swimlane'] == 1): ?>
<?= $this->url->icon('toggle-off', t('Disable'), 'SwimlaneController', 'disableDefault', array('project_id' => $project['id']), true) ?>
<?php else: ?>
<?= $this->url->icon('toggle-on', t('Enable'), 'SwimlaneController', 'enableDefault', array('project_id' => $project['id']), true) ?>
<?php endif ?>
</li>
</ul>
</td>
</tr>
<?php endif ?>
</thead>
<tbody>
<?php foreach ($swimlanes as $swimlane): ?>

View File

@ -27,7 +27,7 @@
<?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
<?= $this->form->select('swimlane_id', $swimlanes_list, $values) ?>
<p class="form-help"><?= t('Current swimlane: %s', $task['swimlane_name'] ?: e($task['default_swimlane'])) ?></p>
<p class="form-help"><?= t('Current swimlane: %s', $task['swimlane_name']) ?></p>
<?= $this->form->label(t('Column'), 'column_id') ?>
<?= $this->form->select('column_id', $columns_list, $values) ?>

View File

@ -28,7 +28,7 @@
<?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
<?= $this->form->select('swimlane_id', $swimlanes_list, $values) ?>
<p class="form-help"><?= t('Current swimlane: %s', $task['swimlane_name'] ?: e($task['default_swimlane'])) ?></p>
<p class="form-help"><?= t('Current swimlane: %s', $task['swimlane_name']) ?></p>
<?= $this->form->label(t('Column'), 'column_id') ?>
<?= $this->form->select('column_id', $columns_list, $values) ?>

View File

@ -26,7 +26,7 @@
<?php endif ?>
</td>
<td>
<?= $this->text->e($task['swimlane_name'] ?: $task['default_swimlane']) ?>
<?= $this->text->e($task['swimlane_name']) ?>
</td>
<td>
<?= $this->text->e($task['column_name']) ?>

View File

@ -57,28 +57,6 @@ class SwimlaneValidator extends BaseValidator
);
}
/**
* Validate default swimlane modification
*
* @access public
* @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateDefaultModification(array $values)
{
$rules = array(
new Validators\Required('id', t('The id is required')),
new Validators\Required('default_swimlane', t('The name is required')),
);
$v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
return array(
$v->execute(),
$v->getErrors()
);
}
/**
* Common validation rules
*

View File

@ -31,6 +31,7 @@ class TaskValidator extends BaseValidator
new Validators\Range('score', t('This value must be in the range %d to %d', -2147483647, 2147483647), -2147483647, 2147483647),
new Validators\Integer('category_id', t('This value must be an integer')),
new Validators\Integer('swimlane_id', t('This value must be an integer')),
new Validators\GreaterThan('swimlane_id', t('This value must be greater than %d', 0), 0),
new Validators\Integer('recurrence_child', t('This value must be an integer')),
new Validators\Integer('recurrence_parent', t('This value must be an integer')),
new Validators\Integer('recurrence_factor', t('This value must be an integer')),

View File

@ -1,41 +1,6 @@
API Swimlane Procedures
=======================
## getDefaultSwimlane
- Purpose: **Get the default swimlane for a project**
- Parameters:
- **project_id** (integer, required)
- Result on success: **true**
- Result on failure: **false**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "getDefaultSwimlane",
"id": 898774713,
"params": [
1
]
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 898774713,
"result": {
"id": "1",
"default_swimlane": "Default swimlane",
"show_default_swimlane": "1"
}
}
```
## getActiveSwimlanes
- Purpose: **Get the list of enabled swimlanes of a project (include default swimlane if enabled)**

View File

@ -537,7 +537,7 @@ Response example:
- **task_id** (integer, required)
- **column_id** (integer, required)
- **position** (integer, required)
- **swimlane_id** (integer, optional, default=0)
- **swimlane_id** (integer, required)
- Result on success: **true**
- Result on failure: **false**

View File

@ -144,7 +144,6 @@ Attribute: **column**
Attribute: **swimlane**
- Find tasks by swim-lane: `swimlane:"Version 42"`
- Find tasks in the default swim-lane: `swimlane:default`
- Find tasks into several swim-lanes: `swimlane:"Version 1.2" swimlane:"Version 1.3"`
### Search by task link

View File

@ -140,7 +140,6 @@ Görev referansı, görevinizin harici bir kimliği, örneğin başka bir yazıl
Özellik: **swimlane**
- Görevleri kulvarlara(swim-lane) göre ara: `swimlane:"Version 42"`
- Görevleri default kulvarlar (swim-lane) göre ara: `swimlane:default`
- Çeşitli kulvarlar (swim-lanes) için görev ara: `swimlane:"Version 1.2" swimlane:"Version 1.3"`
### Görev bağlantısı ile arama

View File

@ -10,13 +10,15 @@ class SwimlaneProcedureTest extends BaseProcedureTest
public function testAll()
{
$this->assertCreateTeamProject();
}
public function assertGetDefaultSwimlane()
{
$swimlane = $this->app->getDefaultSwimlane($this->projectId);
$this->assertNotEmpty($swimlane);
$this->assertEquals('Default swimlane', $swimlane['default_swimlane']);
$this->assertAddSwimlane();
$this->assertGetSwimlane();
$this->assertUpdateSwimlane();
$this->assertDisableSwimlane();
$this->assertEnableSwimlane();
$this->assertGetAllSwimlanes();
$this->assertGetActiveSwimlane();
$this->assertRemoveSwimlane();
$this->assertChangePosition();
}
public function assertAddSwimlane()
@ -60,9 +62,10 @@ class SwimlaneProcedureTest extends BaseProcedureTest
public function assertGetAllSwimlanes()
{
$swimlanes = $this->app->getAllSwimlanes($this->projectId);
$this->assertCount(2, $swimlanes);
$this->assertEquals('Another swimlane', $swimlanes[0]['name']);
$this->assertCount(3, $swimlanes);
$this->assertEquals('Default swimlane', $swimlanes[0]['name']);
$this->assertEquals('Swimlane 2', $swimlanes[1]['name']);
$this->assertEquals('Another swimlane', $swimlanes[2]['name']);
}
public function assertGetActiveSwimlane()
@ -86,7 +89,7 @@ class SwimlaneProcedureTest extends BaseProcedureTest
$this->assertNotFalse($this->app->addSwimlane($this->projectId, 'Swimlane B'));
$swimlanes = $this->app->getAllSwimlanes($this->projectId);
$this->assertCount(3, $swimlanes);
$this->assertCount(4, $swimlanes);
$this->assertTrue($this->app->changeSwimlanePosition($this->projectId, $swimlaneId1, 3));
}

View File

@ -19,7 +19,7 @@ class TaskExportTest extends Base
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Export Project')));
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S1')));
$this->assertEquals(2, $swimlaneModel->create(1, 'S1'));
$this->assertEquals(1, $categoryModel->create(array('name' => 'Category #1', 'project_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array(
@ -34,7 +34,7 @@ class TaskExportTest extends Base
$this->assertEquals(2, $taskCreationModel->create(array(
'project_id' => 1,
'swimlane_id' => 1,
'swimlane_id' => 2,
'title' => 'Task 2',
'date_due' => time(),
)));

View File

@ -20,24 +20,24 @@ class BoardFormatterTest extends Base
$taskFinderModel = new TaskFinderModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
$this->assertEquals(1, $swimlaneModel->create(array('name' => 'Swimlane 1', 'project_id' => 1)));
$this->assertEquals(2, $swimlaneModel->create(array('name' => 'Swimlane 2', 'project_id' => 1)));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane 1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane 2'));
// 2 task within the same column but no score
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task 1', 'project_id' => 1, 'swimlane_id' => 0, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task 2', 'project_id' => 1, 'swimlane_id' => 0, 'column_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task 1', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task 2', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 1)));
// 2 tasks in the same column with score
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'Task 3', 'project_id' => 1, 'swimlane_id' => 0, 'column_id' => 1, 'score' => 4)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'Task 4', 'project_id' => 1, 'swimlane_id' => 0, 'column_id' => 1, 'score' => 5)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'Task 3', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 1, 'score' => 4)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'Task 4', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 1, 'score' => 5)));
// 1 task in 2nd column
$this->assertEquals(5, $taskCreationModel->create(array('title' => 'Task 5', 'project_id' => 1, 'swimlane_id' => 0, 'column_id' => 2)));
$this->assertEquals(5, $taskCreationModel->create(array('title' => 'Task 5', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 2)));
// tasks in same column but different swimlanes
$this->assertEquals(6, $taskCreationModel->create(array('title' => 'Task 6', 'project_id' => 1, 'swimlane_id' => 0, 'column_id' => 3, 'score' => 1)));
$this->assertEquals(7, $taskCreationModel->create(array('title' => 'Task 7', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 3, 'score' => 2)));
$this->assertEquals(8, $taskCreationModel->create(array('title' => 'Task 8', 'project_id' => 1, 'swimlane_id' => 2, 'column_id' => 3, 'score' => 3)));
$this->assertEquals(6, $taskCreationModel->create(array('title' => 'Task 6', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 3, 'score' => 1)));
$this->assertEquals(7, $taskCreationModel->create(array('title' => 'Task 7', 'project_id' => 1, 'swimlane_id' => 2, 'column_id' => 3, 'score' => 2)));
$this->assertEquals(8, $taskCreationModel->create(array('title' => 'Task 8', 'project_id' => 1, 'swimlane_id' => 3, 'column_id' => 3, 'score' => 3)));
$board = BoardFormatter::getInstance($this->container)
->withQuery($taskFinderModel->getExtendedQuery())
@ -46,7 +46,7 @@ class BoardFormatterTest extends Base
$this->assertCount(3, $board);
$this->assertSame(0, $board[0]['id']);
$this->assertSame(1, $board[0]['id']);
$this->assertEquals('Default swimlane', $board[0]['name']);
$this->assertCount(4, $board[0]['columns']);
$this->assertEquals(3, $board[0]['nb_swimlanes']);
@ -85,7 +85,7 @@ class BoardFormatterTest extends Base
$this->assertEquals('Task 5', $board[0]['columns'][1]['tasks'][0]['title']);
$this->assertEquals('Task 6', $board[0]['columns'][2]['tasks'][0]['title']);
$this->assertSame(1, $board[1]['id']);
$this->assertSame(2, $board[1]['id']);
$this->assertEquals('Swimlane 1', $board[1]['name']);
$this->assertCount(4, $board[1]['columns']);
$this->assertEquals(3, $board[1]['nb_swimlanes']);
@ -134,14 +134,14 @@ class BoardFormatterTest extends Base
$taskFinderModel = new TaskFinderModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
$this->assertTrue($swimlaneModel->disableDefault(1));
$this->assertEquals(1, $swimlaneModel->create(array('name' => 'Swimlane 1', 'project_id' => 1)));
$this->assertEquals(2, $swimlaneModel->create(array('name' => 'Swimlane 2', 'project_id' => 1)));
$this->assertTrue($swimlaneModel->disable(1, 1));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane 1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane 2'));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task 1', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task 2', 'project_id' => 1, 'swimlane_id' => 2, 'column_id' => 2)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'Task 3', 'project_id' => 1, 'swimlane_id' => 1, 'column_id' => 2, 'score' => 1)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'Task 4', 'project_id' => 1, 'swimlane_id' => 2, 'column_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task 1', 'project_id' => 1, 'swimlane_id' => 2, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task 2', 'project_id' => 1, 'swimlane_id' => 3, 'column_id' => 2)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'Task 3', 'project_id' => 1, 'swimlane_id' => 2, 'column_id' => 2, 'score' => 1)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'Task 4', 'project_id' => 1, 'swimlane_id' => 3, 'column_id' => 1)));
$board = BoardFormatter::getInstance($this->container)
->withQuery($taskFinderModel->getExtendedQuery())
@ -208,7 +208,7 @@ class BoardFormatterTest extends Base
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
$this->assertTrue($swimlaneModel->disableDefault(1));
$this->assertTrue($swimlaneModel->disable(1, 1));
$board = BoardFormatter::getInstance($this->container)
->withQuery($taskFinderModel->getExtendedQuery())
@ -245,8 +245,8 @@ class BoardFormatterTest extends Base
$taskFinderModel = new TaskFinderModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
$this->assertEquals(1, $swimlaneModel->create(array('name' => 'Swimlane 1', 'project_id' => 1)));
$this->assertEquals(2, $swimlaneModel->create(array('name' => 'Swimlane 2', 'project_id' => 1)));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane 1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane 2'));
$board = BoardFormatter::getInstance($this->container)
->withQuery($taskFinderModel->getExtendedQuery())

View File

@ -162,9 +162,9 @@ class TaskEventJobTest extends Base
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(1, $swimlaneModel->create(array('name' => 'S1', 'project_id' => 1)));
$this->assertEquals(2, $swimlaneModel->create(1, 'S1'));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
$this->assertTrue($taskPositionModel->movePosition(1, 1, 1, 1, 1));
$this->assertTrue($taskPositionModel->movePosition(1, 1, 1, 1, 2));
$called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(TaskModel::EVENT_MOVE_SWIMLANE.'.closure', $called);

View File

@ -24,8 +24,8 @@ class ProjectDuplicationModelTest extends Base
public function testGetSelections()
{
$projectDuplicationModel = new ProjectDuplicationModel($this->container);
$this->assertCount(7, $projectDuplicationModel->getOptionalSelection());
$this->assertCount(8, $projectDuplicationModel->getPossibleSelection());
$this->assertCount(6, $projectDuplicationModel->getOptionalSelection());
$this->assertCount(9, $projectDuplicationModel->getPossibleSelection());
}
public function testGetClonedProjectName()
@ -405,32 +405,31 @@ class ProjectDuplicationModelTest extends Base
$taskCreationModel = new TaskCreationModel($this->container);
$taskFinderModel = new TaskFinderModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'P1', 'default_swimlane' => 'New Default')));
$this->assertEquals(1, $projectModel->create(array('name' => 'P1')));
// create initial swimlanes
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S1')));
$this->assertEquals(2, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S2')));
$this->assertEquals(3, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S3')));
$this->assertEquals(2, $swimlaneModel->create(1, 'S1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'S2'));
$this->assertEquals(4, $swimlaneModel->create(1, 'S3'));
// create initial tasks
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'T0', 'project_id' => 1, 'swimlane_id' => 0)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1, 'swimlane_id' => 1)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'swimlane_id' => 2)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'swimlane_id' => 3)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'T0', 'project_id' => 1, 'swimlane_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1, 'swimlane_id' => 2)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'swimlane_id' => 3)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'swimlane_id' => 4)));
$this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('categoryModel', 'swimlaneModel')));
$swimlanes = $swimlaneModel->getAll(2);
$this->assertCount(3, $swimlanes);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals('S1', $swimlanes[0]['name']);
$this->assertEquals(5, $swimlanes[1]['id']);
$this->assertEquals('S2', $swimlanes[1]['name']);
$this->assertEquals(6, $swimlanes[2]['id']);
$this->assertEquals('S3', $swimlanes[2]['name']);
$swimlane = $swimlaneModel->getDefault(2);
$this->assertEquals('New Default', $swimlane['default_swimlane']);
$this->assertCount(4, $swimlanes);
$this->assertEquals(5, $swimlanes[0]['id']);
$this->assertEquals('Default swimlane', $swimlanes[0]['name']);
$this->assertEquals(6, $swimlanes[1]['id']);
$this->assertEquals('S1', $swimlanes[1]['name']);
$this->assertEquals(7, $swimlanes[2]['id']);
$this->assertEquals('S2', $swimlanes[2]['name']);
$this->assertEquals(8, $swimlanes[3]['id']);
$this->assertEquals('S3', $swimlanes[3]['name']);
// Check if tasks are NOT been duplicated
$this->assertCount(0, $taskFinderModel->getAll(2));
@ -445,7 +444,7 @@ class ProjectDuplicationModelTest extends Base
$this->assertEquals(1, $projectModel->create(array('name' => 'P1')));
// create initial tasks
// Create initial tasks
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3)));
@ -468,12 +467,12 @@ class ProjectDuplicationModelTest extends Base
$taskCreationModel = new TaskCreationModel($this->container);
$taskFinderModel = new TaskFinderModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'P1', 'default_swimlane' => 'New Default')));
$this->assertEquals(1, $projectModel->create(array('name' => 'P1')));
// create initial swimlanes
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S1')));
$this->assertEquals(2, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S2')));
$this->assertEquals(3, $swimlaneModel->create(array('project_id' => 1, 'name' => 'S3')));
$this->assertEquals(2, $swimlaneModel->create(1, 'S1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'S2'));
$this->assertEquals(4, $swimlaneModel->create(1, 'S3'));
// create initial tasks
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 1)));
@ -484,16 +483,15 @@ class ProjectDuplicationModelTest extends Base
// Check if Swimlanes have been duplicated
$swimlanes = $swimlaneModel->getAll(2);
$this->assertCount(3, $swimlanes);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals('S1', $swimlanes[0]['name']);
$this->assertEquals(5, $swimlanes[1]['id']);
$this->assertEquals('S2', $swimlanes[1]['name']);
$this->assertEquals(6, $swimlanes[2]['id']);
$this->assertEquals('S3', $swimlanes[2]['name']);
$swimlane = $swimlaneModel->getDefault(2);
$this->assertEquals('New Default', $swimlane['default_swimlane']);
$this->assertCount(4, $swimlanes);
$this->assertEquals(5, $swimlanes[0]['id']);
$this->assertEquals('Default swimlane', $swimlanes[0]['name']);
$this->assertEquals(6, $swimlanes[1]['id']);
$this->assertEquals('S1', $swimlanes[1]['name']);
$this->assertEquals(7, $swimlanes[2]['id']);
$this->assertEquals('S2', $swimlanes[2]['name']);
$this->assertEquals(8, $swimlanes[3]['id']);
$this->assertEquals('S3', $swimlanes[3]['name']);
// Check if Tasks have been duplicated
$tasks = $taskFinderModel->getAll(2);

View File

@ -0,0 +1,328 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\ProjectModel;
use Kanboard\Model\TaskCreationModel;
use Kanboard\Model\TaskFinderModel;
use Kanboard\Model\SwimlaneModel;
class SwimlaneModelTest extends Base
{
public function testCreation()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$swimlanes = $swimlaneModel->getAll(1);
$this->assertNotEmpty($swimlanes);
$this->assertEquals(2, count($swimlanes));
$this->assertEquals('Default swimlane', $swimlanes[0]['name']);
$this->assertEquals('Swimlane #1', $swimlanes[1]['name']);
$this->assertEquals(2, $swimlaneModel->getIdByName(1, 'Swimlane #1'));
$this->assertEquals(0, $swimlaneModel->getIdByName(2, 'Swimlane #2'));
$this->assertEquals('Default swimlane', $swimlaneModel->getNameById(1));
$this->assertEquals('Swimlane #1', $swimlaneModel->getNameById(2));
$this->assertEquals('', $swimlaneModel->getNameById(23));
}
public function testGetFirstActiveSwimlane()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2'));
$this->assertTrue($swimlaneModel->disable(1, 2));
$swimlane = $swimlaneModel->getFirstActiveSwimlane(1);
$this->assertEquals(1, $swimlane['id']);
$this->assertEquals('Default swimlane', $swimlane['name']);
$this->assertSame(1, $swimlaneModel->getFirstActiveSwimlaneId(1));
$this->assertTrue($swimlaneModel->disable(1, 1));
$swimlane = $swimlaneModel->getFirstActiveSwimlane(1);
$this->assertEquals(3, $swimlane['id']);
$this->assertEquals('Swimlane #2', $swimlane['name']);
$this->assertSame(3, $swimlaneModel->getFirstActiveSwimlaneId(1));
$this->assertTrue($swimlaneModel->disable(1, 3));
$this->assertNull($swimlaneModel->getFirstActiveSwimlane(1));
$this->assertSame(0, $swimlaneModel->getFirstActiveSwimlaneId(1));
}
public function testGetList()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2'));
$swimlanes = $swimlaneModel->getList(1);
$expected = array(
1 => 'Default swimlane',
2 => 'Swimlane #1',
3 => 'Swimlane #2',
);
$this->assertEquals($expected, $swimlanes);
}
public function testUpdate()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertTrue($swimlaneModel->update(array('id' => 2, 'name' => 'foobar')));
$swimlane = $swimlaneModel->getById(2);
$this->assertEquals('foobar', $swimlane['name']);
}
public function testDisableEnable()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$swimlane = $swimlaneModel->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
$this->assertEquals(3, $swimlaneModel->getLastPosition(1));
$this->assertTrue($swimlaneModel->disable(1, 1));
$swimlane = $swimlaneModel->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(0, $swimlane['is_active']);
$this->assertEquals(0, $swimlane['position']);
$this->assertEquals(2, $swimlaneModel->getLastPosition(1));
// Create a new swimlane
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2'));
$swimlane = $swimlaneModel->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
// Enable our disabled swimlane
$this->assertTrue($swimlaneModel->enable(1, 1));
$swimlane = $swimlaneModel->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(3, $swimlane['position']);
}
public function testRemove()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$taskCreationModel = new TaskCreationModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'swimlane_id' => 2)));
$this->assertFalse($swimlaneModel->remove(1, 2));
$this->assertTrue($swimlaneModel->remove(1, 1));
$this->assertEmpty($swimlaneModel->getById(1));
}
public function testUpdatePositions()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2'));
$this->assertEquals(4, $swimlaneModel->create(1, 'Swimlane #3'));
$swimlane = $swimlaneModel->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
$swimlane = $swimlaneModel->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(2, $swimlane['position']);
$swimlane = $swimlaneModel->getById(3);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(3, $swimlane['position']);
// Disable the 2nd swimlane
$this->assertTrue($swimlaneModel->disable(1, 2));
$swimlane = $swimlaneModel->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
$swimlane = $swimlaneModel->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(0, $swimlane['is_active']);
$this->assertEquals(0, $swimlane['position']);
$swimlane = $swimlaneModel->getById(3);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(2, $swimlane['position']);
// Remove the first swimlane
$this->assertTrue($swimlaneModel->remove(1, 1));
$swimlane = $swimlaneModel->getById(1);
$this->assertEmpty($swimlane);
$swimlane = $swimlaneModel->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(0, $swimlane['is_active']);
$this->assertEquals(0, $swimlane['position']);
$swimlane = $swimlaneModel->getById(3);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
}
public function testDuplicateSwimlane()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'P1')));
$this->assertEquals(2, $projectModel->create(array('name' => 'P2')));
$this->assertEquals(3, $swimlaneModel->create(1, 'S1'));
$this->assertEquals(4, $swimlaneModel->create(1, 'S2'));
$this->assertEquals(5, $swimlaneModel->create(1, 'S3'));
$this->assertTrue($swimlaneModel->duplicate(1, 2));
$swimlanes = $swimlaneModel->getAll(2);
$this->assertCount(4, $swimlanes);
$this->assertEquals(2, $swimlanes[0]['id']);
$this->assertEquals('Default swimlane', $swimlanes[0]['name']);
$this->assertEquals(6, $swimlanes[1]['id']);
$this->assertEquals('S1', $swimlanes[1]['name']);
$this->assertEquals(7, $swimlanes[2]['id']);
$this->assertEquals('S2', $swimlanes[2]['name']);
$this->assertEquals(8, $swimlanes[3]['id']);
$this->assertEquals('S3', $swimlanes[3]['name']);
}
public function testChangePosition()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2'));
$this->assertEquals(4, $swimlaneModel->create(1, 'Swimlane #3'));
$this->assertEquals(5, $swimlaneModel->create(1, 'Swimlane #4'));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(2, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(3, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 3, 2));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(3, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(2, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 2, 1));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(2, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(1, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(3, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 2, 2));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(2, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(3, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 4, 1));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(1, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(2, $swimlanes[2]['id']);
$this->assertFalse($swimlaneModel->changePosition(1, 2, 0));
$this->assertFalse($swimlaneModel->changePosition(1, 2, 8));
}
public function testChangePositionWithInactiveSwimlane()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2'));
$this->assertEquals(4, $swimlaneModel->create(1, 'Swimlane #3'));
$this->assertEquals(5, $swimlaneModel->create(1, 'Swimlane #4'));
$this->assertTrue($swimlaneModel->disable(1, 2));
$this->assertTrue($swimlaneModel->disable(1, 3));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(4, $swimlanes[1]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 4, 1));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(1, $swimlanes[1]['id']);
}
}

View File

@ -1,370 +0,0 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\ProjectModel;
use Kanboard\Model\TaskCreationModel;
use Kanboard\Model\TaskFinderModel;
use Kanboard\Model\SwimlaneModel;
class SwimlaneTest extends Base
{
public function testCreation()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$swimlanes = $s->getSwimlanes(1);
$this->assertNotEmpty($swimlanes);
$this->assertEquals(2, count($swimlanes));
$this->assertEquals('Default swimlane', $swimlanes[0]['name']);
$this->assertEquals('Swimlane #1', $swimlanes[1]['name']);
$this->assertEquals(1, $s->getIdByName(1, 'Swimlane #1'));
$this->assertEquals(0, $s->getIdByName(2, 'Swimlane #2'));
$this->assertEquals('Swimlane #1', $s->getNameById(1));
$this->assertEquals('', $s->getNameById(23));
}
public function testGetFirstActiveSwimlane()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1', 'is_active' => 0)));
$this->assertEquals(2, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #2')));
$swimlane = $swimlaneModel->getFirstActiveSwimlane(1);
$this->assertEquals(0, $swimlane['id']);
$this->assertEquals('Default swimlane', $swimlane['name']);
$this->assertTrue($swimlaneModel->disableDefault(1));
$swimlane = $swimlaneModel->getFirstActiveSwimlane(1);
$this->assertEquals(2, $swimlane['id']);
$this->assertEquals('Swimlane #2', $swimlane['name']);
$this->assertTrue($swimlaneModel->disable(1, 2));
$this->assertNull($swimlaneModel->getFirstActiveSwimlane(1));
}
public function testGetList()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertEquals(2, $s->create(array('project_id' => 1, 'name' => 'Swimlane #2')));
$swimlanes = $s->getList(1);
$expected = array('Default swimlane', 'Swimlane #1', 'Swimlane #2');
$this->assertEquals($expected, $swimlanes);
}
public function testUpdate()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals('Swimlane #1', $swimlane['name']);
$this->assertTrue($s->update(array('id' => 1, 'name' => 'foobar')));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals('foobar', $swimlane['name']);
}
public function testUpdateDefaultSwimlane()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertTrue($s->updateDefault(array('id' => 1, 'default_swimlane' => 'foo', 'show_default_swimlane' => 1)));
$default = $s->getDefault(1);
$this->assertNotEmpty($default);
$this->assertEquals('foo', $default['default_swimlane']);
$this->assertEquals(1, $default['show_default_swimlane']);
$this->assertTrue($s->updateDefault(array('id' => 1, 'default_swimlane' => 'foo', 'show_default_swimlane' => 0)));
$default = $s->getDefault(1);
$this->assertNotEmpty($default);
$this->assertEquals('foo', $default['default_swimlane']);
$this->assertEquals(0, $default['show_default_swimlane']);
}
public function testDisableEnableDefaultSwimlane()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'UnitTest')));
$this->assertTrue($swimlaneModel->disableDefault(1));
$default = $swimlaneModel->getDefault(1);
$this->assertEquals(0, $default['show_default_swimlane']);
$this->assertTrue($swimlaneModel->enableDefault(1));
$default = $swimlaneModel->getDefault(1);
$this->assertEquals(1, $default['show_default_swimlane']);
}
public function testDisableEnable()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
$this->assertEquals(2, $s->getLastPosition(1));
$this->assertTrue($s->disable(1, 1));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(0, $swimlane['is_active']);
$this->assertEquals(0, $swimlane['position']);
$this->assertEquals(1, $s->getLastPosition(1));
// Create a new swimlane
$this->assertEquals(2, $s->create(array('project_id' => 1, 'name' => 'Swimlane #2')));
$swimlane = $s->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
// Enable our disabled swimlane
$this->assertTrue($s->enable(1, 1));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(2, $swimlane['position']);
}
public function testRemove()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$tc = new TaskCreationModel($this->container);
$tf = new TaskFinderModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'swimlane_id' => 1)));
$task = $tf->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertTrue($s->remove(1, 1));
$task = $tf->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEmpty($s->getById(1));
}
public function testUpdatePositions()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertEquals(2, $s->create(array('project_id' => 1, 'name' => 'Swimlane #2')));
$this->assertEquals(3, $s->create(array('project_id' => 1, 'name' => 'Swimlane #3')));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
$swimlane = $s->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(2, $swimlane['position']);
$swimlane = $s->getById(3);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(3, $swimlane['position']);
// Disable the 2nd swimlane
$this->assertTrue($s->disable(1, 2));
$swimlane = $s->getById(1);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
$swimlane = $s->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(0, $swimlane['is_active']);
$this->assertEquals(0, $swimlane['position']);
$swimlane = $s->getById(3);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(2, $swimlane['position']);
// Remove the first swimlane
$this->assertTrue($s->remove(1, 1));
$swimlane = $s->getById(1);
$this->assertEmpty($swimlane);
$swimlane = $s->getById(2);
$this->assertNotEmpty($swimlane);
$this->assertEquals(0, $swimlane['is_active']);
$this->assertEquals(0, $swimlane['position']);
$swimlane = $s->getById(3);
$this->assertNotEmpty($swimlane);
$this->assertEquals(1, $swimlane['is_active']);
$this->assertEquals(1, $swimlane['position']);
}
public function testDuplicateSwimlane()
{
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'P1')));
$this->assertEquals(2, $p->create(array('name' => 'P2')));
$this->assertEquals(1, $s->create(array('project_id' => 1, 'name' => 'S1')));
$this->assertEquals(2, $s->create(array('project_id' => 1, 'name' => 'S2')));
$this->assertEquals(3, $s->create(array('project_id' => 1, 'name' => 'S3')));
$default_swimlane1 = $s->getDefault(1);
$default_swimlane1['default_swimlane'] = 'New Default';
$this->assertTrue($s->updateDefault($default_swimlane1));
$this->assertTrue($s->duplicate(1, 2));
$swimlanes = $s->getAll(2);
$this->assertCount(3, $swimlanes);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals('S1', $swimlanes[0]['name']);
$this->assertEquals(5, $swimlanes[1]['id']);
$this->assertEquals('S2', $swimlanes[1]['name']);
$this->assertEquals(6, $swimlanes[2]['id']);
$this->assertEquals('S3', $swimlanes[2]['name']);
$new_default = $s->getDefault(2);
$this->assertEquals('New Default', $new_default['default_swimlane']);
}
public function testChangePosition()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertEquals(2, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #2')));
$this->assertEquals(3, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #3')));
$this->assertEquals(4, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #4')));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(2, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(3, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 3, 2));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(3, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(2, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 2, 1));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(2, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(1, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(3, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 2, 2));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(2, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(3, $swimlanes[2]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 4, 1));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(1, $swimlanes[1]['id']);
$this->assertEquals(3, $swimlanes[2]['position']);
$this->assertEquals(2, $swimlanes[2]['id']);
$this->assertFalse($swimlaneModel->changePosition(1, 2, 0));
$this->assertFalse($swimlaneModel->changePosition(1, 2, 5));
}
public function testChangePositionWithInactiveSwimlane()
{
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertEquals(2, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #2', 'is_active' => 0)));
$this->assertEquals(3, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #3', 'is_active' => 0)));
$this->assertEquals(4, $swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #4')));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(1, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(4, $swimlanes[1]['id']);
$this->assertTrue($swimlaneModel->changePosition(1, 4, 1));
$swimlanes = $swimlaneModel->getAllByStatus(1);
$this->assertEquals(1, $swimlanes[0]['position']);
$this->assertEquals(4, $swimlanes[0]['id']);
$this->assertEquals(2, $swimlanes[1]['position']);
$this->assertEquals(1, $swimlanes[1]['id']);
}
}

View File

@ -90,7 +90,7 @@ class TaskDuplicationModelTest extends Base
$this->assertEquals(1, $task['project_id']);
$this->assertEquals(1, $task['owner_id']);
$this->assertEquals(2, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(3, $task['column_id']);
$this->assertEquals(2, $task['position']);
$this->assertEquals('test', $task['title']);

View File

@ -51,7 +51,7 @@ class TaskFinderModelTest extends Base
$this->assertEquals(0, $task['score']);
$this->assertEquals(1, $task['category_id']);
$this->assertEquals(0, $task['priority']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(TaskModel::RECURRING_STATUS_NONE, $task['recurrence_status']);
$this->assertEquals(TaskModel::RECURRING_TRIGGER_FIRST_COLUMN, $task['recurrence_trigger']);
$this->assertEquals(0, $task['recurrence_factor']);
@ -60,8 +60,7 @@ class TaskFinderModelTest extends Base
$this->assertEquals(0, $task['recurrence_parent']);
$this->assertEquals(0, $task['recurrence_child']);
$this->assertEquals('C1', $task['category_name']);
$this->assertNull($task['swimlane_name']);
$this->assertEquals('Default swimlane', $task['default_swimlane']);
$this->assertEquals('Default swimlane', $task['swimlane_name']);
$this->assertEquals('Project #1', $task['project_name']);
$this->assertEquals('Backlog', $task['column_title']);
$this->assertEquals('admin', $task['assignee_username']);

View File

@ -422,7 +422,7 @@ class TaskPositionModelTest extends Base
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'test 1')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #2', 'project_id' => 1, 'column_id' => 1)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'Task #3', 'project_id' => 1, 'column_id' => 1)));
@ -430,60 +430,60 @@ class TaskPositionModelTest extends Base
$this->assertEquals(5, $taskCreationModel->create(array('title' => 'Task #5', 'project_id' => 1, 'column_id' => 1)));
// Move the task to the swimlane
$this->assertTrue($taskPositionModel->movePosition(1, 1, 2, 1, 1));
$this->assertTrue($taskPositionModel->movePosition(1, 1, 2, 1, 2));
// Check tasks position
$task = $taskFinderModel->getById(1);
$this->assertEquals(1, $task['id']);
$this->assertEquals(2, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$task = $taskFinderModel->getById(2);
$this->assertEquals(2, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$task = $taskFinderModel->getById(3);
$this->assertEquals(3, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(2, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$task = $taskFinderModel->getById(4);
$this->assertEquals(4, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(3, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
// Move the task to the swimlane
$this->assertTrue($taskPositionModel->movePosition(1, 2, 2, 1, 1));
$this->assertTrue($taskPositionModel->movePosition(1, 2, 2, 1, 2));
// Check tasks position
$task = $taskFinderModel->getById(1);
$this->assertEquals(1, $task['id']);
$this->assertEquals(2, $task['column_id']);
$this->assertEquals(2, $task['position']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$task = $taskFinderModel->getById(2);
$this->assertEquals(2, $task['id']);
$this->assertEquals(2, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$task = $taskFinderModel->getById(3);
$this->assertEquals(3, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$task = $taskFinderModel->getById(4);
$this->assertEquals(4, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(2, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
// Move the task 5 to the last column
$this->assertTrue($taskPositionModel->movePosition(1, 5, 4, 1, 0));
@ -493,31 +493,31 @@ class TaskPositionModelTest extends Base
$this->assertEquals(1, $task['id']);
$this->assertEquals(2, $task['column_id']);
$this->assertEquals(2, $task['position']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$task = $taskFinderModel->getById(2);
$this->assertEquals(2, $task['id']);
$this->assertEquals(2, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$task = $taskFinderModel->getById(3);
$this->assertEquals(3, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$task = $taskFinderModel->getById(4);
$this->assertEquals(4, $task['id']);
$this->assertEquals(1, $task['column_id']);
$this->assertEquals(2, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$task = $taskFinderModel->getById(5);
$this->assertEquals(5, $task['id']);
$this->assertEquals(4, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
}
public function testEvents()
@ -529,7 +529,7 @@ class TaskPositionModelTest extends Base
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
$this->assertEquals(1, $swimlaneModel->create(array('project_id' => 1, 'name' => 'test 1')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'column_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #2', 'project_id' => 1, 'column_id' => 2)));
@ -573,19 +573,19 @@ class TaskPositionModelTest extends Base
$this->assertEquals(2, count($called));
// Move to another swimlane
$this->assertTrue($taskPositionModel->movePosition(1, 1, 3, 1, 1));
$this->assertTrue($taskPositionModel->movePosition(1, 1, 3, 1, 2));
$task = $taskFinderModel->getById(1);
$this->assertEquals(1, $task['id']);
$this->assertEquals(3, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(1, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$task = $taskFinderModel->getById(2);
$this->assertEquals(2, $task['id']);
$this->assertEquals(2, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(1, $task['swimlane_id']);
$called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(TaskModel::EVENT_MOVE_SWIMLANE.'.TaskPositionModelTest::onMoveSwimlane', $called);
@ -626,6 +626,6 @@ class TaskPositionModelTest extends Base
$this->assertEquals(1, $event_data['position']);
$this->assertEquals(3, $event_data['column_id']);
$this->assertEquals(1, $event_data['project_id']);
$this->assertEquals(1, $event_data['swimlane_id']);
$this->assertEquals(2, $event_data['swimlane_id']);
}
}

View File

@ -55,7 +55,7 @@ class TaskProjectDuplicationModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(0, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(6, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(2, $task['project_id']);
@ -91,7 +91,7 @@ class TaskProjectDuplicationModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(2, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(6, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(2, $task['project_id']);
@ -149,8 +149,8 @@ class TaskProjectDuplicationModelTest extends Base
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $projectModel->create(array('name' => 'test2')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 2, 'name' => 'Swimlane #1')));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(4, $swimlaneModel->create(2, 'Swimlane #2'));
// We create a task
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 1)));
@ -182,11 +182,11 @@ class TaskProjectDuplicationModelTest extends Base
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $projectModel->create(array('name' => 'test2')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 2, 'name' => 'Swimlane #2')));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(4, $swimlaneModel->create(1, 'Swimlane #2'));
// We create a task
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 2)));
// We duplicate our task to the 2nd project
$this->assertEquals(2, $taskProjectDuplicationModel->duplicateToProject(1, 2));
@ -196,7 +196,7 @@ class TaskProjectDuplicationModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(0, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(6, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(2, $task['project_id']);
@ -215,12 +215,12 @@ class TaskProjectDuplicationModelTest extends Base
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $projectModel->create(array('name' => 'test2')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 2, 'name' => 'Swimlane #1')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 2, 'name' => 'Swimlane #2')));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(4, $swimlaneModel->create(2, 'Swimlane #1'));
$this->assertEquals(5, $swimlaneModel->create(2, 'Swimlane #2'));
// We create a task
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 2)));
// We duplicate our task to the 2nd project
$this->assertEquals(2, $taskProjectDuplicationModel->duplicateToProject(1, 2, 3));
@ -228,7 +228,7 @@ class TaskProjectDuplicationModelTest extends Base
// Check the values of the duplicated task
$task = $taskFinderModel->getById(2);
$this->assertNotEmpty($task);
$this->assertEquals(3, $task['swimlane_id']);
$this->assertEquals(4, $task['swimlane_id']);
}
public function testDuplicateAnotherProjectWithPredefinedColumn()

View File

@ -61,7 +61,7 @@ class TaskProjectMoveModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(0, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(2, $task['project_id']);
$this->assertEquals(5, $task['column_id']);
$this->assertEquals(1, $task['position']);
@ -97,7 +97,7 @@ class TaskProjectMoveModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(2, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(6, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(2, $task['project_id']);
@ -182,11 +182,11 @@ class TaskProjectMoveModelTest extends Base
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $projectModel->create(array('name' => 'test2')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 2, 'name' => 'Swimlane #1')));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(4, $swimlaneModel->create(2, 'Swimlane #1'));
// We create a task
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 3)));
// We move our task to the 2nd project
$this->assertTrue($taskProjectMoveModel->moveToProject(1, 2));
@ -196,7 +196,7 @@ class TaskProjectMoveModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(0, $task['category_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(4, $task['swimlane_id']);
$this->assertEquals(6, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(2, $task['project_id']);
@ -215,11 +215,11 @@ class TaskProjectMoveModelTest extends Base
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(2, $projectModel->create(array('name' => 'test2')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 1, 'name' => 'Swimlane #1')));
$this->assertNotFalse($swimlaneModel->create(array('project_id' => 2, 'name' => 'Swimlane #2')));
$this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(4, $swimlaneModel->create(2, 'Swimlane #2'));
// We create a task
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 1)));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'swimlane_id' => 3)));
// We move our task to the 2nd project
$this->assertTrue($taskProjectMoveModel->moveToProject(1, 2));
@ -229,7 +229,7 @@ class TaskProjectMoveModelTest extends Base
$this->assertNotEmpty($task);
$this->assertEquals(0, $task['owner_id']);
$this->assertEquals(0, $task['category_id']);
$this->assertEquals(0, $task['swimlane_id']);
$this->assertEquals(2, $task['swimlane_id']);
$this->assertEquals(6, $task['column_id']);
$this->assertEquals(1, $task['position']);
$this->assertEquals(2, $task['project_id']);

View File

@ -0,0 +1,143 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\SwimlaneModel;
use Kanboard\Model\SubtaskModel;
use Kanboard\Model\TaskModel;
use Kanboard\Model\TaskCreationModel;
use Kanboard\Model\TaskFinderModel;
use Kanboard\Model\TaskStatusModel;
use Kanboard\Model\ProjectModel;
class TaskStatusModelTest extends Base
{
public function testCloseBySwimlaneAndColumn()
{
$taskCreationModel = new TaskCreationModel($this->container);
$taskFinderModel = new TaskFinderModel($this->container);
$taskStatusModel = new TaskStatusModel($this->container);
$projectModel = new ProjectModel($this->container);
$swimlaneModel = new SwimlaneModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1'));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1)));
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2)));
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'swimlane_id' => 2)));
$this->assertEquals(5, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'is_active' => 0, 'date_completed' => strtotime('2015-01-01'))));
$taskBefore = $taskFinderModel->getById(5);
$this->assertEquals(2, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(1, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 2));
$this->assertEquals(1, $taskFinderModel->countByColumnAndSwimlaneId(1, 2, 1));
$taskStatusModel->closeTasksBySwimlaneAndColumn(1, 1);
$this->assertEquals(0, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(1, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 2));
$this->assertEquals(1, $taskFinderModel->countByColumnAndSwimlaneId(1, 2, 1));
$taskStatusModel->closeTasksBySwimlaneAndColumn(2, 1);
$this->assertEquals(0, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(0, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 2));
$this->assertEquals(1, $taskFinderModel->countByColumnAndSwimlaneId(1, 2, 1));
$taskStatusModel->closeTasksBySwimlaneAndColumn(1, 2);
$this->assertEquals(0, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(0, $taskFinderModel->countByColumnAndSwimlaneId(1, 1, 2));
$this->assertEquals(0, $taskFinderModel->countByColumnAndSwimlaneId(1, 2, 1));
$taskAfter = $taskFinderModel->getById(5);
$this->assertEquals(strtotime('2015-01-01'), $taskAfter['date_completed']);
$this->assertEquals($taskBefore['date_modification'], $taskAfter['date_modification']);
}
public function testStatus()
{
$taskCreationModel = new TaskCreationModel($this->container);
$taskFinderModel = new TaskFinderModel($this->container);
$taskStatusModel = new TaskStatusModel($this->container);
$projectModel = new ProjectModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1)));
// The task must be open
$this->assertTrue($taskStatusModel->isOpen(1));
$task = $taskFinderModel->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(TaskModel::STATUS_OPEN, $task['is_active']);
$this->assertEquals(0, $task['date_completed']);
$this->assertEquals(time(), $task['date_modification'], '', 1);
// We close the task
$this->container['dispatcher']->addListener(TaskModel::EVENT_CLOSE, array($this, 'onTaskClose'));
$this->container['dispatcher']->addListener(TaskModel::EVENT_OPEN, array($this, 'onTaskOpen'));
$this->assertTrue($taskStatusModel->close(1));
$this->assertTrue($taskStatusModel->isClosed(1));
$task = $taskFinderModel->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(TaskModel::STATUS_CLOSED, $task['is_active']);
$this->assertEquals(time(), $task['date_completed'], 'Bad completion timestamp', 1);
$this->assertEquals(time(), $task['date_modification'], 'Bad modification timestamp', 1);
// We open the task again
$this->assertTrue($taskStatusModel->open(1));
$this->assertTrue($taskStatusModel->isOpen(1));
$task = $taskFinderModel->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(TaskModel::STATUS_OPEN, $task['is_active']);
$this->assertEquals(0, $task['date_completed']);
$this->assertEquals(time(), $task['date_modification'], '', 1);
$called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey('task.close.TaskStatusModelTest::onTaskClose', $called);
$this->assertArrayHasKey('task.open.TaskStatusModelTest::onTaskOpen', $called);
}
public function onTaskOpen($event)
{
$this->assertInstanceOf('Kanboard\Event\TaskEvent', $event);
$this->assertArrayHasKey('task_id', $event);
$this->assertNotEmpty($event['task_id']);
}
public function onTaskClose($event)
{
$this->assertInstanceOf('Kanboard\Event\TaskEvent', $event);
$this->assertArrayHasKey('task_id', $event);
$this->assertNotEmpty($event['task_id']);
}
public function testThatAllSubtasksAreClosed()
{
$taskStatusModel = new TaskStatusModel($this->container);
$taskCreationModel = new TaskCreationModel($this->container);
$subtaskModel = new SubtaskModel($this->container);
$projectModel = new ProjectModel($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
$this->assertEquals(2, $subtaskModel->create(array('title' => 'subtask #2', 'task_id' => 1)));
$this->assertTrue($taskStatusModel->close(1));
$subtasks = $subtaskModel->getAll(1);
$this->assertNotEmpty($subtasks);
foreach ($subtasks as $subtask) {
$this->assertEquals(SubtaskModel::STATUS_DONE, $subtask['status']);
}
}
}

View File

@ -1,143 +0,0 @@
<?php
require_once __DIR__.'/../Base.php';
use Kanboard\Model\SwimlaneModel;
use Kanboard\Model\SubtaskModel;
use Kanboard\Model\TaskModel;
use Kanboard\Model\TaskCreationModel;
use Kanboard\Model\TaskFinderModel;
use Kanboard\Model\TaskStatusModel;
use Kanboard\Model\ProjectModel;
class TaskStatusTest extends Base
{
public function testCloseBySwimlaneAndColumn()
{
$tc = new TaskCreationModel($this->container);
$tf = new TaskFinderModel($this->container);
$ts = new TaskStatusModel($this->container);
$p = new ProjectModel($this->container);
$s = new SwimlaneModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $s->create(array('name' => 'test', 'project_id' => 1)));
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));
$this->assertEquals(2, $tc->create(array('title' => 'test', 'project_id' => 1)));
$this->assertEquals(3, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2)));
$this->assertEquals(4, $tc->create(array('title' => 'test', 'project_id' => 1, 'swimlane_id' => 1)));
$this->assertEquals(5, $tc->create(array('title' => 'test', 'project_id' => 1, 'is_active' => 0, 'date_completed' => strtotime('2015-01-01'))));
$taskBefore = $tf->getById(5);
$this->assertEquals(2, $tf->countByColumnAndSwimlaneId(1, 1, 0));
$this->assertEquals(1, $tf->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(1, $tf->countByColumnAndSwimlaneId(1, 2, 0));
$ts->closeTasksBySwimlaneAndColumn(0, 1);
$this->assertEquals(0, $tf->countByColumnAndSwimlaneId(1, 1, 0));
$this->assertEquals(1, $tf->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(1, $tf->countByColumnAndSwimlaneId(1, 2, 0));
$ts->closeTasksBySwimlaneAndColumn(1, 1);
$this->assertEquals(0, $tf->countByColumnAndSwimlaneId(1, 1, 0));
$this->assertEquals(0, $tf->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(1, $tf->countByColumnAndSwimlaneId(1, 2, 0));
$ts->closeTasksBySwimlaneAndColumn(0, 2);
$this->assertEquals(0, $tf->countByColumnAndSwimlaneId(1, 1, 0));
$this->assertEquals(0, $tf->countByColumnAndSwimlaneId(1, 1, 1));
$this->assertEquals(0, $tf->countByColumnAndSwimlaneId(1, 2, 0));
$taskAfter = $tf->getById(5);
$this->assertEquals(strtotime('2015-01-01'), $taskAfter['date_completed']);
$this->assertEquals($taskBefore['date_modification'], $taskAfter['date_modification']);
}
public function testStatus()
{
$tc = new TaskCreationModel($this->container);
$tf = new TaskFinderModel($this->container);
$ts = new TaskStatusModel($this->container);
$p = new ProjectModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1)));
// The task must be open
$this->assertTrue($ts->isOpen(1));
$task = $tf->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(TaskModel::STATUS_OPEN, $task['is_active']);
$this->assertEquals(0, $task['date_completed']);
$this->assertEquals(time(), $task['date_modification'], '', 1);
// We close the task
$this->container['dispatcher']->addListener(TaskModel::EVENT_CLOSE, array($this, 'onTaskClose'));
$this->container['dispatcher']->addListener(TaskModel::EVENT_OPEN, array($this, 'onTaskOpen'));
$this->assertTrue($ts->close(1));
$this->assertTrue($ts->isClosed(1));
$task = $tf->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(TaskModel::STATUS_CLOSED, $task['is_active']);
$this->assertEquals(time(), $task['date_completed'], 'Bad completion timestamp', 1);
$this->assertEquals(time(), $task['date_modification'], 'Bad modification timestamp', 1);
// We open the task again
$this->assertTrue($ts->open(1));
$this->assertTrue($ts->isOpen(1));
$task = $tf->getById(1);
$this->assertNotEmpty($task);
$this->assertEquals(TaskModel::STATUS_OPEN, $task['is_active']);
$this->assertEquals(0, $task['date_completed']);
$this->assertEquals(time(), $task['date_modification'], '', 1);
$called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey('task.close.TaskStatusTest::onTaskClose', $called);
$this->assertArrayHasKey('task.open.TaskStatusTest::onTaskOpen', $called);
}
public function onTaskOpen($event)
{
$this->assertInstanceOf('Kanboard\Event\TaskEvent', $event);
$this->assertArrayHasKey('task_id', $event);
$this->assertNotEmpty($event['task_id']);
}
public function onTaskClose($event)
{
$this->assertInstanceOf('Kanboard\Event\TaskEvent', $event);
$this->assertArrayHasKey('task_id', $event);
$this->assertNotEmpty($event['task_id']);
}
public function testThatAllSubtasksAreClosed()
{
$ts = new TaskStatusModel($this->container);
$tc = new TaskCreationModel($this->container);
$s = new SubtaskModel($this->container);
$p = new ProjectModel($this->container);
$this->assertEquals(1, $p->create(array('name' => 'test1')));
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
$this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1)));
$this->assertTrue($ts->close(1));
$subtasks = $s->getAll(1);
$this->assertNotEmpty($subtasks);
foreach ($subtasks as $subtask) {
$this->assertEquals(SubtaskModel::STATUS_DONE, $subtask['status']);
}
}
}

View File

@ -39,4 +39,15 @@ class TaskValidatorTest extends Base
$result = $taskValidator->validateCreation(array('project_id' => 1, 'title' => 'test', 'score' => -2147483648));
$this->assertFalse($result[0]);
}
public function testSwimlaneIdField()
{
$taskValidator = new TaskValidator($this->container);
$result = $taskValidator->validateCreation(array('project_id' => 1, 'title' => 'test', 'swimlane_id' => 1));
$this->assertTrue($result[0]);
$result = $taskValidator->validateCreation(array('project_id' => 1, 'title' => 'test', 'swimlane_id' => 0));
$this->assertFalse($result[0]);
}
}