Allow to associate tags to colors

The color is then used as background in the board, list and task details
views
This commit is contained in:
Julian Maurice
2018-08-09 21:35:11 +02:00
parent ae3ade0908
commit 9d4cd31e1a
24 changed files with 69 additions and 27 deletions

View File

@@ -28,6 +28,7 @@ class ProjectTagController extends BaseController
$this->response->html($this->template->render('project_tag/create', array( $this->response->html($this->template->render('project_tag/create', array(
'project' => $project, 'project' => $project,
'values' => $values, 'values' => $values,
'colors' => $this->colorModel->getList(),
'errors' => $errors, 'errors' => $errors,
))); )));
} }
@@ -41,7 +42,7 @@ class ProjectTagController extends BaseController
list($valid, $errors) = $this->tagValidator->validateCreation($values); list($valid, $errors) = $this->tagValidator->validateCreation($values);
if ($valid) { if ($valid) {
if ($this->tagModel->create($project['id'], $values['name']) > 0) { if ($this->tagModel->create($project['id'], $values['name'], $values['color_id']) > 0) {
$this->flash->success(t('Tag created successfully.')); $this->flash->success(t('Tag created successfully.'));
} else { } else {
$this->flash->failure(t('Unable to create this tag.')); $this->flash->failure(t('Unable to create this tag.'));
@@ -66,6 +67,7 @@ class ProjectTagController extends BaseController
'project' => $project, 'project' => $project,
'tag' => $tag, 'tag' => $tag,
'values' => $values, 'values' => $values,
'colors' => $this->colorModel->getList(),
'errors' => $errors, 'errors' => $errors,
))); )));
} }
@@ -81,7 +83,7 @@ class ProjectTagController extends BaseController
list($valid, $errors) = $this->tagValidator->validateModification($values); list($valid, $errors) = $this->tagValidator->validateModification($values);
if ($valid) { if ($valid) {
if ($this->tagModel->update($values['id'], $values['name'])) { if ($this->tagModel->update($values['id'], $values['name'], $values['color_id'])) {
$this->flash->success(t('Tag updated successfully.')); $this->flash->success(t('Tag updated successfully.'));
} else { } else {
$this->flash->failure(t('Unable to update this tag.')); $this->flash->failure(t('Unable to update this tag.'));

View File

@@ -28,6 +28,7 @@ class TagController extends BaseController
$this->response->html($this->template->render('tag/create', array( $this->response->html($this->template->render('tag/create', array(
'values' => $values, 'values' => $values,
'colors' => $this->colorModel->getList(),
'errors' => $errors, 'errors' => $errors,
))); )));
} }
@@ -38,7 +39,7 @@ class TagController extends BaseController
list($valid, $errors) = $this->tagValidator->validateCreation($values); list($valid, $errors) = $this->tagValidator->validateCreation($values);
if ($valid) { if ($valid) {
if ($this->tagModel->create(0, $values['name']) > 0) { if ($this->tagModel->create(0, $values['name'], $values['color_id']) > 0) {
$this->flash->success(t('Tag created successfully.')); $this->flash->success(t('Tag created successfully.'));
} else { } else {
$this->flash->failure(t('Unable to create this tag.')); $this->flash->failure(t('Unable to create this tag.'));
@@ -62,6 +63,7 @@ class TagController extends BaseController
$this->response->html($this->template->render('tag/edit', array( $this->response->html($this->template->render('tag/edit', array(
'tag' => $tag, 'tag' => $tag,
'values' => $values, 'values' => $values,
'colors' => $this->colorModel->getList(),
'errors' => $errors, 'errors' => $errors,
))); )));
} }
@@ -78,7 +80,7 @@ class TagController extends BaseController
} }
if ($valid) { if ($valid) {
if ($this->tagModel->update($values['id'], $values['name'])) { if ($this->tagModel->update($values['id'], $values['name'], $values['color_id'])) {
$this->flash->success(t('Tag updated successfully.')); $this->flash->success(t('Tag updated successfully.'));
} else { } else {
$this->flash->failure(t('Unable to update this tag.')); $this->flash->failure(t('Unable to update this tag.'));

View File

@@ -74,7 +74,7 @@ class TaskViewController extends BaseController
'internal_links' => $this->taskLinkModel->getAllGroupedByLabel($task['id']), 'internal_links' => $this->taskLinkModel->getAllGroupedByLabel($task['id']),
'external_links' => $this->taskExternalLinkModel->getAll($task['id']), 'external_links' => $this->taskExternalLinkModel->getAll($task['id']),
'link_label_list' => $this->linkModel->getList(0, false), 'link_label_list' => $this->linkModel->getList(0, false),
'tags' => $this->taskTagModel->getList($task['id']), 'tags' => $this->taskTagModel->getTagsByTask($task['id']),
))); )));
} }

View File

@@ -218,7 +218,7 @@ class ColorModel extends Base
$buffer = ''; $buffer = '';
foreach ($this->default_colors as $color => $values) { foreach ($this->default_colors as $color => $values) {
$buffer .= '.task-board.color-'.$color.', .task-summary-container.color-'.$color.', .color-picker-square.color-'.$color.', .task-board-category.color-'.$color.', .table-list-category.color-'.$color.' {'; $buffer .= '.task-board.color-'.$color.', .task-summary-container.color-'.$color.', .color-picker-square.color-'.$color.', .task-board-category.color-'.$color.', .table-list-category.color-'.$color.', .task-tag.color-'.$color.' {';
$buffer .= 'background-color: '.$values['background'].';'; $buffer .= 'background-color: '.$values['background'].';';
$buffer .= 'border-color: '.$values['border']; $buffer .= 'border-color: '.$values['border'];
$buffer .= '}'; $buffer .= '}';

View File

@@ -143,11 +143,12 @@ class TagModel extends Base
* @param string $tag * @param string $tag
* @return bool|int * @return bool|int
*/ */
public function create($project_id, $tag) public function create($project_id, $tag, $color_id = null)
{ {
return $this->db->table(self::TABLE)->persist(array( return $this->db->table(self::TABLE)->persist(array(
'project_id' => $project_id, 'project_id' => $project_id,
'name' => $tag, 'name' => $tag,
'color_id' => $color_id,
)); ));
} }
@@ -159,10 +160,11 @@ class TagModel extends Base
* @param string $tag * @param string $tag
* @return bool * @return bool
*/ */
public function update($tag_id, $tag) public function update($tag_id, $tag, $color_id)
{ {
return $this->db->table(self::TABLE)->eq('id', $tag_id)->update(array( return $this->db->table(self::TABLE)->eq('id', $tag_id)->update(array(
'name' => $tag, 'name' => $tag,
'color_id' => $color_id,
)); ));
} }

View File

@@ -46,7 +46,7 @@ class TaskTagModel extends Base
public function getTagsByTask($task_id) public function getTagsByTask($task_id)
{ {
return $this->db->table(TagModel::TABLE) return $this->db->table(TagModel::TABLE)
->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name') ->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name', TagModel::TABLE.'.color_id')
->eq(self::TABLE.'.task_id', $task_id) ->eq(self::TABLE.'.task_id', $task_id)
->join(self::TABLE, 'tag_id', 'id') ->join(self::TABLE, 'tag_id', 'id')
->findAll(); ->findAll();
@@ -66,7 +66,7 @@ class TaskTagModel extends Base
} }
$tags = $this->db->table(TagModel::TABLE) $tags = $this->db->table(TagModel::TABLE)
->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name', self::TABLE.'.task_id') ->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name', TagModel::TABLE.'.color_id', self::TABLE.'.task_id')
->in(self::TABLE.'.task_id', $task_ids) ->in(self::TABLE.'.task_id', $task_ids)
->join(self::TABLE, 'tag_id', 'id') ->join(self::TABLE, 'tag_id', 'id')
->asc(TagModel::TABLE.'.name') ->asc(TagModel::TABLE.'.name')

View File

@@ -8,7 +8,12 @@ use PDO;
use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role; use Kanboard\Core\Security\Role;
const VERSION = 132; const VERSION = 133;
function version_133(PDO $pdo)
{
$pdo->exec('ALTER TABLE `tags` ADD COLUMN `color_id` VARCHAR(50) DEFAULT NULL');
}
function version_132(PDO $pdo) function version_132(PDO $pdo)
{ {

View File

@@ -8,7 +8,12 @@ use PDO;
use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role; use Kanboard\Core\Security\Role;
const VERSION = 110; const VERSION = 111;
function version_111(PDO $pdo)
{
$pdo->exec('ALTER TABLE "tags" ADD COLUMN "color_id" VARCHAR(50) DEFAULT NULL');
}
function version_110(PDO $pdo) function version_110(PDO $pdo)
{ {

View File

@@ -522,6 +522,7 @@ CREATE TABLE `tags` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`project_id` int(11) NOT NULL, `project_id` int(11) NOT NULL,
`color_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `project_id` (`project_id`,`name`) UNIQUE KEY `project_id` (`project_id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -927,7 +927,8 @@ ALTER SEQUENCE "swimlanes_id_seq" OWNED BY "swimlanes"."id";
CREATE TABLE "tags" ( CREATE TABLE "tags" (
"id" integer NOT NULL, "id" integer NOT NULL,
"name" character varying(255) NOT NULL, "name" character varying(255) NOT NULL,
"project_id" integer NOT NULL "project_id" integer NOT NULL,
"color_id" character varying(255)
); );

View File

@@ -8,7 +8,12 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role; use Kanboard\Core\Security\Role;
use PDO; use PDO;
const VERSION = 119; const VERSION = 120;
function version_120(PDO $pdo)
{
$pdo->exec('ALTER TABLE tags ADD COLUMN color_id TEXT DEFAULT NULL');
}
function version_119(PDO $pdo) function version_119(PDO $pdo)
{ {

View File

@@ -25,7 +25,7 @@
<div class="task-tags"> <div class="task-tags">
<ul> <ul>
<?php foreach ($task['tags'] as $tag): ?> <?php foreach ($task['tags'] as $tag): ?>
<li><?= $this->text->e($tag['name']) ?></li> <li class="task-tag <?= $tag['color_id'] ? "color-{$tag['color_id']}" : '' ?>"><?= $this->text->e($tag['name']) ?></li>
<?php endforeach ?> <?php endforeach ?>
</ul> </ul>
</div> </div>

View File

@@ -7,5 +7,8 @@
<?= $this->form->label(t('Name'), 'name') ?> <?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?> <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?>
<?= $this->form->label(t('Color'), 'color_id') ?>
<?= $this->form->select('color_id', array('' => t('No color')) + $colors, $values, $errors, array(), 'color-picker') ?>
<?= $this->modal->submitButtons() ?> <?= $this->modal->submitButtons() ?>
</form> </form>

View File

@@ -7,5 +7,8 @@
<?= $this->form->label(t('Name'), 'name') ?> <?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?> <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?>
<?= $this->form->label(t('Color'), 'color_id') ?>
<?= $this->form->select('color_id', array('' => t('No color')) + $colors, $values, $errors, array(), 'color-picker') ?>
<?= $this->modal->submitButtons() ?> <?= $this->modal->submitButtons() ?>
</form> </form>

View File

@@ -8,5 +8,8 @@
<?= $this->form->label(t('Name'), 'name') ?> <?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?> <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?>
<?= $this->form->label(t('Color'), 'color_id') ?>
<?= $this->form->select('color_id', array('' => t('No color')) + $colors, $values, $errors, array(), 'color-picker') ?>
<?= $this->modal->submitButtons() ?> <?= $this->modal->submitButtons() ?>
</form> </form>

View File

@@ -9,5 +9,8 @@
<?= $this->form->label(t('Name'), 'name') ?> <?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?> <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="191"')) ?>
<?= $this->form->label(t('Color'), 'color_id') ?>
<?= $this->form->select('color_id', array('' => t('No color')) + $colors, $values, $errors, array(), 'color-picker') ?>
<?= $this->modal->submitButtons() ?> <?= $this->modal->submitButtons() ?>
</form> </form>

View File

@@ -156,7 +156,7 @@
<div class="task-tags"> <div class="task-tags">
<ul> <ul>
<?php foreach ($tags as $tag): ?> <?php foreach ($tags as $tag): ?>
<li><?= $this->text->e($tag) ?></li> <li class="task-tag <?= $tag['color_id'] ? "color-{$tag['color_id']}" : '' ?>"><?= $this->text->e($tag['name']) ?></li>
<?php endforeach ?> <?php endforeach ?>
</ul> </ul>
</div> </div>

View File

@@ -25,7 +25,7 @@
<?php endif ?> <?php endif ?>
<?php foreach ($task['tags'] as $tag): ?> <?php foreach ($task['tags'] as $tag): ?>
<span class="table-list-category task-list-tag"> <span class="table-list-category task-list-tag <?= $tag['color_id'] ? "color-{$tag['color_id']}" : '' ?>">
<?= $this->text->e($tag['name']) ?> <?= $this->text->e($tag['name']) ?>
</span> </span>
<?php endforeach ?> <?php endforeach ?>

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,3 @@
.task-summary-container .task-tags .task-summary-container .task-tags
margin-top: 10px margin-top: 10px
.task-list-tag
background: #ffeb8e
border-color: #333

View File

@@ -375,11 +375,13 @@ class BoardFormatterTest extends Base
'id' => 1, 'id' => 1,
'name' => 'My tag 1', 'name' => 'My tag 1',
'task_id' => 1, 'task_id' => 1,
'color_id' => null,
), ),
array( array(
'id' => 2, 'id' => 2,
'name' => 'My tag 2', 'name' => 'My tag 2',
'task_id' => 1, 'task_id' => 1,
'color_id' => null,
), ),
); );
@@ -391,6 +393,7 @@ class BoardFormatterTest extends Base
'id' => 3, 'id' => 3,
'name' => 'My tag 3', 'name' => 'My tag 3',
'task_id' => 2, 'task_id' => 2,
'color_id' => null,
), ),
); );

View File

@@ -37,11 +37,13 @@ class TaskListFormatterTest extends Base
'id' => 1, 'id' => 1,
'name' => 'My tag 1', 'name' => 'My tag 1',
'task_id' => 1, 'task_id' => 1,
'color_id' => null,
), ),
array( array(
'id' => 2, 'id' => 2,
'name' => 'My tag 2', 'name' => 'My tag 2',
'task_id' => 1, 'task_id' => 1,
'color_id' => null,
), ),
); );
@@ -52,10 +54,11 @@ class TaskListFormatterTest extends Base
'id' => 3, 'id' => 3,
'name' => 'My tag 3', 'name' => 'My tag 3',
'task_id' => 2, 'task_id' => 2,
'color_id' => null,
), ),
); );
$this->assertEquals($expected, $listing[1]['tags']); $this->assertEquals($expected, $listing[1]['tags']);
$this->assertEquals(array(), $listing[2]['tags']); $this->assertEquals(array(), $listing[2]['tags']);
} }
} }

View File

@@ -111,10 +111,11 @@ class TagModelTest extends Base
{ {
$tagModel = new TagModel($this->container); $tagModel = new TagModel($this->container);
$this->assertEquals(1, $tagModel->create(0, 'Tag 1')); $this->assertEquals(1, $tagModel->create(0, 'Tag 1'));
$this->assertTrue($tagModel->update(1, 'Tag Updated')); $this->assertTrue($tagModel->update(1, 'Tag Updated', 'purple'));
$tag = $tagModel->getById(1); $tag = $tagModel->getById(1);
$this->assertEquals(0, $tag['project_id']); $this->assertEquals(0, $tag['project_id']);
$this->assertEquals('Tag Updated', $tag['name']); $this->assertEquals('Tag Updated', $tag['name']);
$this->assertEquals('purple', $tag['color_id']);
} }
} }

View File

@@ -86,17 +86,20 @@ class TaskTagModelTest extends Base
array( array(
'id' => 1, 'id' => 1,
'name' => 'My tag 1', 'name' => 'My tag 1',
'task_id' => 1 'task_id' => 1,
'color_id' => null,
), ),
array( array(
'id' => 2, 'id' => 2,
'name' => 'My tag 2', 'name' => 'My tag 2',
'task_id' => 1 'task_id' => 1,
'color_id' => null,
), ),
array( array(
'id' => 3, 'id' => 3,
'name' => 'My tag 3', 'name' => 'My tag 3',
'task_id' => 1 'task_id' => 1,
'color_id' => null,
), ),
), ),
2 => array( 2 => array(
@@ -104,6 +107,7 @@ class TaskTagModelTest extends Base
'id' => 3, 'id' => 3,
'name' => 'My tag 3', 'name' => 'My tag 3',
'task_id' => 2, 'task_id' => 2,
'color_id' => null,
) )
) )
); );